Dual-Write Outbox and Inbox Pattern¶
Workflow — instantiates Bidirectional Consistency Mapping
Persists intended changes and idempotent receipt so propagation survives partial failure.
The Dual-Write Outbox and Inbox Pattern is the delivery workflow that guarantees a change made on one side actually reaches the other even when a process crashes, a network drops, or a broker redelivers. Its defining move is refusing to write to the local database and publish to the partner in two separate steps — because a crash between them loses the update or invents a phantom one. Instead the workflow records the intended propagation in an outbox inside the very same local transaction that makes the business change, so the two commit or fail together; a separate relay then delivers outbox rows, and the receiver's inbox consults a deduplication ledger before applying each one, so a redelivery is recognized rather than reapplied. The pattern is about atomicity and at-least-once delivery of intent, not about transforming values or resolving who wins — it makes sure the change survives the trip.
Example¶
An online retailer's order-management service accepts a cancellation. In one database transaction it both marks the order cancelled and inserts an outbox row: {change_id: c-8842, origin: oms, op: cancel, order: 4471}. Either both land or neither does — there is no window where the order is cancelled but the fulfillment side never hears about it. A relay process reads new outbox rows and delivers them to the warehouse fulfillment service. Suppose the relay crashes after delivering c-8842 but before marking it sent; on restart it redelivers. The fulfillment service's inbox checks its deduplication ledger, finds c-8842 already applied, so it recognizes the duplicate, skips re-cancelling, and acknowledges. Setup to outcome: a cancellation that a plain "save then call the API" integration could silently drop — or double-apply — instead arrives exactly-effectively-once despite the crash.
How it works¶
- Outbox inside the transaction. The intended propagation is written atomically with the local state change, so committing the business change and recording the obligation to propagate it are one act.
- Relay with retry. A separate reader ships outbox rows to the partner, retrying until acknowledged; it may crash and redeliver freely because delivery is at-least-once by design.
- Inbox on receipt. The receiver's inbox consults the deduplication ledger it consumes, so an already-applied change is skipped and at-least-once delivery becomes effectively-once application.
- Governed cadence. The relay honors the propagation policy — batching, ordering per entity, and latency targets — so bursts do not overwhelm the partner and per-record order is preserved.
Tuning parameters¶
- Outbox drain latency — how quickly the relay ships rows. Tight latency narrows the inconsistency window but raises load and reduces batching gains.
- Ordering guarantee — global, per-entity, or none. Per-entity ordering is usually enough and far cheaper than global ordering.
- Retry and backoff schedule — how persistently undelivered rows are retried before parking; aggressive retry cuts lag but can amplify a partner outage.
- Outbox retention — how long delivered rows are kept for audit and replay before compaction; longer retention aids recovery but grows the table.
- Delivery cadence — event-triggered versus periodic batch; triggered is fresher, batched is calmer under load.
When it helps, and when it misleads¶
Its strength is turning "did the change actually make it across?" from a hope into a guarantee. Because the obligation to propagate is committed atomically with the change itself, no partial failure can silently drop or fabricate an update — the outbox is the durable record of intent and the inbox the durable record of receipt.[n1]
Its failure mode is believing reliable delivery equals correctness. The pattern guarantees the change arrives and applies once; it says nothing about whether the arriving change should overwrite a newer independent edit, or whether the value survived its transform. The classic misuse is treating a drained outbox as proof of consistency while stale overwrites and dropped fields accumulate underneath. The guarding discipline is to pair the workflow with authority and conflict rules that decide, at apply time, whether a reliably delivered change is actually allowed to win.
How it implements the components¶
causal_change_identity_and_origin— each outbox row carries a stable change identity, source side, and operation, which is exactly what the inbox keys on to recognize a redelivery.scoped_authority_and_propagation_policy— the relay enforces the propagation half of policy: when changes flow, in what order, at what batch size and latency, and how retries are governed.
It does not implement bidirectional_conflict_and_exception_policy or human_adjudication_and_contestation_path — that is its workflow twin the Synchronization Conflict Queue, which holds and resolves changes this pattern merely delivers. It also does not implement echo_idempotence_and_fixed_point_guard itself; the inbox defers dedup to the Idempotency and Deduplication Ledger.
Related¶
- Instantiates: Bidirectional Consistency Mapping — supplies the reliable, atomic delivery of change intent the rest of the machinery assumes.
- Consumes: Idempotency and Deduplication Ledger — the inbox uses it to make redelivery harmless.
- Sibling mechanisms: Synchronization Conflict Queue · Bidirectional Change-Data-Capture Adapter · Synchronization Origin Token · Field-Level Authority Matrix
Editorial Notes¶
Form Classification¶
Form family: Control, Automation & Runtime
Rationale: Dual-Write Outbox and Inbox Pattern operates as a live operational control that automatically routes, enforces, adapts, or responds during execution because it persists intended changes and idempotent receipt so propagation survives partial failure.
Independent corroboration: The frozen evidence defines Dual-Write Outbox and Inbox Pattern as 'Persists intended changes and idempotent receipt so propagation survives partial failure', so its operative form is Control, Automation & Runtime.
Nearest alternative: Protocol, Workflow & Routine — Outbox persistence, relay retries, and inbox deduplication execute automatically during propagation, beyond a documented workflow.
Review outcome: Independent reviewer agreement; medium confidence.
Origin Attribution¶
Primary origin: Computer Science & Software Engineering
Origin pattern: Single lineage
Present-day reach: Specialized
Rationale: Distributed-systems engineering cohered the transactional outbox plus idempotent inbox to make state changes and retryable message propagation reliable without a cross-system transaction.
Review outcome: Independent reviewer agreement; high confidence.
Notes¶
[n1] The transactional outbox — recording an outgoing message in the same local transaction as the state change it reports, so the message and the change share a single commit. A companion inbox (or "idempotent receiver") records processed message identities so redelivery is safe. Together they give reliable, effectively-once propagation without a distributed transaction across the two systems. ↩