Distributed systems often need one business action to update multiple independent systems. That is where reliability breaks most often.
The root issue is simple: these systems do not share one atomic transaction boundary.
Architecture
A modern, practical approach to handling dual writes when one business action must propagate across independent systems.
Distributed systems often need one business action to update multiple independent systems. That is where reliability breaks most often.
The root issue is simple: these systems do not share one atomic transaction boundary.
Problem
A single action may need to propagate to heterogeneous targets such as:
If one operation succeeds and another fails, state diverges. This is not a finance-specific issue. It is a general distributed systems problem.
Pattern
The Outbox Pattern makes one local system authoritative for the state change, and records external propagation tasks durably in the same local commit.
Instead of writing directly to every external target during the request, you commit local business state and outbox records in one transaction, then let background jobs process those outbox records reliably.
Example
This use case starts when the user confirms a withdrawal amount and destination address. From this action, the platform must coordinate updates across partner systems, blockchain execution, and event propagation without losing consistency.
withdrawals is the business source of truth.
id (UUID), user_idasset, network, amountdestination_addressstatus (REQUESTED, BROADCASTED, CONFIRMED, FAILED)tx_hash, failure_reasonrequested_at, broadcasted_at, confirmed_atcreated_at, updated_atoutbox_events is the durable integration queue.
id (UUID)aggregate_type (WITHDRAWAL)aggregate_id (references withdrawals.id)event_type (for example WITHDRAWAL_REQUESTED, PARTNER_SYNC_REQUESTED, BLOCKCHAIN_BROADCAST_REQUESTED, WITHDRAWAL_CONFIRMED)payload (JSON), idempotency_keystatus (PENDING, PROCESSING, DONE, RETRYING, FAILED)attempt_count, next_retry_at, last_errorcreated_at, updated_atOutboxDispatcherJob
PENDING eventsPROCESSINGevent_type to partner sync, blockchain broadcast, or event publishOutboxRetryJob
RETRYINGattempt_count and schedules next_retry_atOutboxFailureJob
FAILED when retry limit is reached or error is non-retryableWithdrawalConfirmationJob
withdrawals.status to CONFIRMEDOperations
RETRYING: last attempt failed, automatic retry is scheduledFAILED: terminal state, no more automatic retriesWith this design, failures become visible and actionable instead of silent data divergence.
Conclusion
The Outbox Pattern is a practical reliability pattern for heterogeneous architectures. When a business action must propagate across systems that cannot commit atomically together, Outbox keeps state and side effects aligned.