Outbox Pattern: Reliable Event Publishing in Microservices | Microservices Tutorials

Updated July 2026. Refreshed for current microservices best practices.

The Dual-Write Problem

When a service saves to its database AND publishes to Kafka, either operation can fail independently. You might persist an order but never publish the event — or publish without saving. The Outbox pattern solves this with a single atomic transaction.

How the Outbox Pattern Works

  1. Begin database transaction.
  2. Insert/update business data (e.g., orders table).
  3. Insert event row into outbox table in the same transaction.
  4. Commit transaction — both writes succeed or both roll back.
  5. Separate relay process polls outbox, publishes to Kafka, marks rows as sent.

Outbox Table Schema

CREATE TABLE outbox (
  id UUID PRIMARY KEY,
  aggregate_type VARCHAR(100),
  aggregate_id VARCHAR(100),
  event_type VARCHAR(100),
  payload JSONB,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  published_at TIMESTAMPTZ
);

Relay Worker Best Practices

  • Poll in batches with FOR UPDATE SKIP LOCKED for concurrency.
  • Make Kafka publishes idempotent (use event ID as key).
  • Retry with exponential backoff on broker failures.
  • Monitor outbox lag (unpublished row count).

Alternatives: Debezium CDC reads database WAL and streams changes to Kafka without polling. Related: Saga Pattern · Kafka Topics Guide


Want live microservices classes? Join Alkademy for instructor-led microservices architecture courses with hands-on projects.

Go deeper with the book: Practical Microservices Design Using CQRS and Event Sourcing by Kindson Munonye.

Kindson Munonye is a software engineer and technical author specializing in microservices, CQRS, event sourcing, and distributed systems. He publishes free step-by-step tutorials and live classes on Alkademy.