The Lost Order Mystery: Dual-Writes vs. Transactional Outbox

Simulate silent data loss under network failure with naive dual-writes vs guaranteed consistency with the Transactional Outbox pattern.

Architecture Lab // Data Integrity & Distributed Consistency

The Lost Order: Dual-Writes vs. Transactional Outbox

System Integrity:100% CONSISTENT
Database Ledger:100 / 100 Paid
Warehouse Dispatched:100 / 100 Shipped
play_circleScenarios:
receipt_long
The Real-World Analogy: The Carbon-Copy Receipt at the Register

Imagine buying a laptop at a store register. Step 1: The cashier charges your card \$1,500. Step 2: The cashier phones the warehouse across town to dispatch your box. If the phone line dies right between step 1 and step 2, your card was billed, but the warehouse never got the memo! The Transactional Outbox prints a carbon copy into the local register drawer (the database transaction). Even if the phone line cuts out for an hour, the courier delivers the copy as soon as the line reconnects.

Interactive Distributed Architecture Map
End-to-End Order & Message Lifecycle
NETWORK WIRE: CONNECTED (0% DROP)
storageTrack 1: Local Database Ledger
ATOMIC COMMIT
Checkout Execution Path:
Step 1: INSERT INTO orders (id, amount, status)✓ SUCCESS (100)
Step 2: INSERT INTO outbox_events✓ ATOMIC COMMIT
PostgreSQL Committed Rows:100 Orders in DB
TABLE: ordersALL 100 COMMITTED
#ord_9901 .. #ord_1000$189.50
STATUS: PAID
TABLE: outbox_events100 Events Synced
Event: OrderPaid(0 pending in buffer)
PUBLISHED
hubTrack 2: Transport & Warehouse
100% AT-LEAST-ONCE
TCP Wire Connection:CONNECTED
cableNetwork Socket: Nominal (0ms Latency)
TCP ACK
KAFKA BROKER: orders.events.v1100 / 100 Messages Received
Total Ingress Packets:100 / 100 Delivered
Lost on Wire:0 Lost Orders
local_shippingWAREHOUSE FULFILLMENT POD100% Match
Packages Dispatched:100 Shipped
Consumer Deduplication:0 Duplicates (Idempotent)
verifiedThe Solution: Transactional Outbox Guarantees Zero Data Loss

By saving the order and the message event inside the exact same local database transaction, it is mathematically impossible for one to commit without the other. Even if the network cable to Kafka drops for 10 minutes, the background relay safely retries when connectivity returns. Zero ghost orders, 100% reliable fulfillment!

tuneRelay Strategy & Consumer Deduplication Playground
PostgreSQL WAL CDC (Debezium)

PostgreSQL Write-Ahead Log (WAL) streams committed events straight into Kafka without issuing heavy polling queries or causing table lock contention.

Enabled (ON CONFLICT DO NOTHING)Protects warehouse against double-shipping physical items upon network replay.
build_circlePRODUCTION REMEDIATION PLAYBOOK
Engineering Defenses Against Dual-Write Data Corruption
1. Single Local ACID Transaction

Never perform network RPCs across different systems inside web handlers. Write the business state change and the event payload into the same database transaction. Either both commit, or neither does.

2. Log-Based CDC Relay

Deploy Debezium or inspect PostgreSQL WAL directly (pgoutput). The relay reads committed WAL records and publishes them to Kafka with at-least-once delivery, bypassing application code completely.

3. Consumer Idempotency Keys

Because distributed relays guarantee at-least-once delivery, downstream consumers use idempotency tables (INSERT ... ON CONFLICT (event_id) DO NOTHING) to guarantee exactly-once processing effects.

Experiencing architectural bottlenecks in production?

From connection starvation and p99 latency spikes to Kafka consumer lag, index optimization, and algorithm profiling.

handshakeDiscuss Your Architecture