Production-grade by default.
The happy path is the easy part.
A dropped connection. A slow write. A worker that restarts halfway through a job. A provider that stops answering.
I design systems around what happens next. Domain logic never touches infrastructure or transport directly. State changes and background work have explicit boundaries. Side effects are durable, retriable, and observable, never best-effort.
The infrastructure can change. The boundaries should not.
The infrastructure changes. The boundaries don't.
Every system I build roughly* reduces to the same small set of boundaries. The technologies underneath can change. The responsibilities shouldn't.
Typed end-to-end. Transport concerns stay at the edge; the client shapes the experience, not the domain logic.
The boundary. Validation, Auth, Versioning. No business rules live in the transport layer.
Where the business actually lives. Framework-agnostic, infrastructure-blind, and explicitly testable.
The absolute source of truth. State changes and the intent to do background work are committed in one atomic transaction. A write that doesn't survive a crash isn't done.
Infra for asynchronous work. Decouples state persistence from downstream processing.
Durable execution. Payments, AI processing, external integrations, anything slow. Retried on failure, strictly logged, out of the request path. Provider outages are absorbed here.
Good systems make the wrong dependencies difficult.
Transport shouldn't own business rules. The domain shouldn't know whether the database is Postgres or Mongo. Application code shouldn't know whether a job runs on BullMQ or Asynq.
Dependency flows inward, never the other way.
feature/ api/v1/ # router, handlers, DTOs domain/ # pure models, services infra/ # repos, workers, queues
Adding api/v2/ touches exactly one folder. domain/ and infra/ don't move. Versioning enforced by structure, not convention.
State changes and intent should agree.
When a request changes state and also needs background work done, those two facts should never quietly disagree. The database records both in one atomic transaction: the state change, and the intent to perform the work. The worker executes that intent independently of the original request.
State says "send it." Nothing will.
Work exists for a state that never committed.
The outbox closes that gap.
Background work should behave like work, not a promise.
Anything slow, failure-prone, or externally dependent leaves the request path: payments, emails, AI processing, external integrations. The worker owns execution. The system records attempts. Failures retry in a controlled way, and side effects are safe to repeat.
This isn't exactly-once execution. Distributed systems don't get that claim for free. The goal is durable intent, controlled retries, and idempotent effects.
If it fails, it should also leave evidence: what was requested, what state it reached, how many attempts happened, where execution stopped, and why. That's logs, execution history, request context, and traces tied together, not a single dashboard promising visibility it can't deliver.
External systems are allowed to fail.
A provider isn't part of your reliability boundary. It's a failure boundary.
| When this fails | User sees | Worker does |
|---|---|---|
| Payment provider down | Payment not confirmed | Retries with a scoped idempotency key; nothing marked paid without confirmation |
| Email provider down | Nothing, not in their path | Queued and retried, execution recorded |
A few rules that don't move
Each invariant isolates a specific system failure mode, from atomic local persistence up to the external provider boundary, preventing partial completion and data inconsistency.
Same principles, different problems.
DreamStack
The infrastructure is the product. The problem is making execution durable, observable, and replaceable.
View DreamStack →SiteStamp
The input is messy, physical-world evidence. The problem is turning it into structured, traceable output.
View SiteStamp →Build for the second failure.
Shipping fast only matters if the system survives production.The happy path is easy. I design for what happens when a provider times out, the network drops, or a process dies halfway through a job.