pattern

Outbox Relay

The process that reads pending messages from an outbox table and publishes them to a broker, providing at-least-once delivery with no distributed transaction.

The outbox pattern writes the business change and the message to be published in one local database transaction, so they cannot diverge. The relay is what gets the message out afterwards.

Two implementations:

Polling — query the table for unpublished rows, publish, mark as sent. Simple, works everywhere, and adds query load plus latency proportional to the poll interval.

Change data capture — read the database transaction log and publish rows as they are committed. No polling load, lower latency, and it requires log access and a CDC pipeline to operate.

Properties that follow, and must be designed for:

Delivery is at-least-once. The relay can publish and fail before marking the row sent, so consumers must be idempotent on a message ID. This is not a defect to fix; it is the guarantee the pattern provides.

Ordering is preserved only if the relay publishes in sequence and the destination partition is chosen by a consistent key.

The table needs pruning, or it grows without limit and degrades the queries that use it.

The problem it solves is the dual write: updating a database and publishing a message as two separate operations, where any failure between them leaves the system inconsistent with no way to detect it.