Skip to content
Go back

80/20 Of The Week: The Outbox Pattern

Edit page

80/20 Of The Week … The Outbox Pattern

Posting this because recently I talked about this a fair bit lol… now…

One of the most common problems in backend systems sounds simple:

How do you update the database and publish an event safely?

At first glance, it sounds easy.

You save the data, you publish the event and done.

Except… production systems don’t work that nicely.

  1. The problem

Imagine this flow:

Order gets created in the database, service then publishes OrderCreated event and at the end another service listens and starts payment, notification, shipping, etc…

Sounds fine.

But what if your service crashes after the DB write succeeds and before the event is published?

Now you have:

the order saved in the database but no event was sent and downstream services never find out about it

So your system is already inconsistent.

  1. Why naive solutions fail

A common first thought is:

“Fine, then publish the event first and save to the DB after.”

That just flips the problem.

Now the event might be published, but the database write may fail.

So consumers react to something that never actually became true in your system since you cannot roll back the event publish.

  1. The Outbox idea

The Outbox Pattern solves this by changing the flow.

Instead of doing: write business data publish event

you do this in the same database transaction:

write the business data and then write the event into an outbox table

That’s it.

So when an order is created, you also insert something like:

𝘦𝘷𝘦𝘯𝘵 𝘵𝘺𝘱𝘦 = 𝘖𝘳𝘥𝘦𝘳𝘊𝘳𝘦𝘢𝘵𝘦𝘥

𝘱𝘢𝘺𝘭𝘰𝘢𝘥 = 𝘰𝘳𝘥𝘦𝘳 𝘥𝘦𝘵𝘢𝘪𝘭𝘴

𝘴𝘵𝘢𝘵𝘶𝘴 = 𝘱𝘦𝘯𝘥𝘪𝘯𝘨

Both the business row and the outbox row are committed together.

Which means:

  1. What happens next

A separate background process then:

reads pending events from the outbox table

publishes them to Kafka / RabbitMQ / whatever broker you use

marks them as processed

Basically don’t try to atomically update the DB and the broker directly.

Atomically update the DB and the intent to publish.

That intent lives in the outbox.

  1. Why it works

Because now your source of truth is consistent.

If the business transaction commits, the event is definitely recorded.

Even if the service crashes right after, the outbox processor can still publish it later.

So you don’t lose the event.

That’s the real strength of the pattern.

  1. But it’s not magic

Outbox is powerful, but it doesn’t make distributed systems “easy.”

You still need to think about:

duplicate delivery

the publisher may retry and send the same event more than once

idempotent consumers

consumers should handle duplicates safely

ordering

some event flows care about strict order, which can get tricky

cleanup

outbox tables grow, so retention/archiving matters

monitoring

if outbox publishing gets stuck, your system silently lags behind reality

So Outbox is not “problem solved forever.”

It’s more like:

problem moved into a safer and more controllable form

  1. Main takeaway

The Outbox Pattern is useful because it avoids this nightmare scenario:

DB updated successfully, event never sent.

And that exact failure mode is one of the most dangerous in event-driven systems, because it often looks fine at first…

until another service quietly stops reacting to reality.

Final thought

Outbox isn’t about fancy architecture.

It’s about respecting one uncomfortable truth:

the moment you mix database writes and broker publishes, partial failure becomes part of the design.

And Outbox is one of the cleanest ways to handle that.

#Backend #SystemDesign #DistributedSystems #Microservices #Kafka #Architecture #SoftwareEngineering

The Outbox Pattern


Edit page
Share this post on:

Previous Post
80/20 Of The Week: Rate Limiting and Backpressure
Next Post
80/20 Of The Week: Partitioning and Sharding