4.3 h
of failed checkouts a month
Six of the 11 calls form a chain. Assume each service is up 99.9%, failing independently: 0.999⁶ ≈ 99.4%, against 43 minutes for one service.
Ask five teams what an “order” is. Get five answers.
Each keeps only the fields it needs, linked by the order ID. Inside each bounded context, one model and its words mean one thing.
Where do you cut?
Bad: One service per table
Logic leaks into callers, and Order becomes a hub everyone calls.
Good: Where the language changes
Each context owns its model and data, and changes for one reason.
Stick the business on a wall. The seams appear.
Domain experts post past-tense events on a timeline. Cut where a pivotal event splits the flow, and where “order” suddenly becomes “ticket”.
Placing an order also creates a kitchen ticket. One transaction for both?
Whose job is it?
Accepting the order is the restaurant’s job, not the customer’s. So it commits alone; OrderPlaced creates the ticket seconds later.
Sync only where a person waits. Events everywhere else.
Starting payment is the one call; the customer is staring at the screen. Kitchen, Dispatch and Notifications can be down ten minutes without failing one checkout.
A bounded context isn’t automatically a microservice
- Start contexts as modules in one deployable
- Extract a service once a seam proves itself
- Never smaller than an aggregate, nor larger than a context
The interview line
Cut where the language changes, not by table. Each context owns its data; across contexts, IDs and events.