Engineering patterns

Choose a pattern for the failure it solves.

Compare implementation patterns using the business constraint, the operational cost and the recovery behaviour.

Explore the comparisonDownload PDF
On this page

Three ways to connect a business event

PatternUse it when
Synchronous API
The caller needs a result immediately and can handle a bounded failure
Transactional outbox
A database change and its outgoing event must stay consistent
Reconciliation job
Systems can disagree temporarily and need a dependable repair path

Start with the consistency requirement

Define what must be true together, what may become consistent later and how a discrepancy will be detected. That decision narrows the suitable patterns.

Include the operator in the design

A queue needs replay rules. An outbox needs a dispatcher. A reconciliation job needs an exception owner. The pattern is incomplete without its operating path.

Explain the tradeoff behind a pattern

A pattern captures a recurring problem and the conditions under which one approach works. A queue can absorb a burst of work, but introduces delay, repeated delivery and another operating dependency. A cache reduces repeated reads, but creates a freshness decision. Describing only the advantage encourages adoption without the controls that make the design dependable.

Keep the business consequence visible. If a delayed event leaves a customer viewing an old order status, decide whether that delay is acceptable and how the interface communicates it. A pattern suitable for an analytics feed may need additional coordination before it can support stock reservation. Begin with the requirement, then assess whether the pattern fits.

A repeated-write example

A caller submits an order and times out before receiving confirmation. Retrying can create another order if the first request succeeded. An idempotency design associates the logical operation with a stable key and records the result so a repeated request can return the earlier outcome. The important detail is the boundary between recording that key and performing the business change.

Ask what happens if execution stops between those steps, how long the key remains valid and whether a different payload can reuse it. Test concurrent requests as well as sequential retries. When an external provider owns the final write, local deduplication may not resolve an uncertain provider outcome. The design then needs a reconciliation path.

Record conditions for safe adoption

For each pattern, document prerequisites, failure modes, observability needs and operating cost. Include a small example and a counterexample. An outbox can coordinate a database change with event publication, but still needs a publisher, duplicate handling and a way to investigate messages that cannot be delivered.

Review the proposal against the team's actual constraints. An application with one deployment and one data store may not benefit from the complexity appropriate to a large distributed system. Prefer the simplest design that meets the requirements and leaves a manageable recovery path. A pattern library should improve engineering judgement rather than become a checklist of components every project is expected to install.

It can decouple work, but introduces ordering, duplication and operational concerns. Use it when those tradeoffs solve a real workload problem.