2026 field guide

Refreshed for cloud-native, multi-region, streaming, and AI infrastructure.

Explore 41 concepts →
Search DistillSys

Find a concept

Type at least two characters to search lessons, designs, papers, and interview prep.

Transactionsintermediate7 min read

Transactional Outbox

Publish events reliably by committing business state and message intent in one local transaction.

2–5 minute refresher
Mental model

Commit the fact and the promise to publish together; deliver the promise asynchronously.

30second
refresher
A service writes its domain change and an outbox row in the same database transaction. A relay or change-data-capture pipeline later publishes the row to the broker and marks progress.

What problem does it solve?

Writing a database and broker separately creates a dual-write gap: either the state commits without its event or the event publishes without the state.

How it works

  1. Begin the local database transaction.
  2. Write the domain state and immutable outbox record.
  3. Commit them together.
  4. Relay unpublished records with stable event IDs.
  5. Publish at least once and let consumers deduplicate.
Decision guide

Key trade-offs

ChoiceWhat you gainWhat it costs
Polling relayPortable and simplePolling latency and load
CDC relayLow-latency ordered captureOperational coupling to logs
Delete after sendSmall tableHarder audit and replay
What happens if?

Publish succeeds before acknowledgement

The broker accepts an event, but the relay crashes before recording progress. The event is published again after restart; without consumer idempotency the business effect repeats.

Where it appears

  • Order services
  • Payment workflows
  • Cache invalidation
  • Audit pipelines
Senior interview modeDoes an outbox provide exactly-once delivery?Show answer
No. It provides atomic state-plus-intent and normally at-least-once publication. Exactly-once business outcomes still require stable event identity, idempotent consumers, and careful handling of external effects.
#outbox#CDC#events#dual writes