Outbox Pattern Providing Reliable Messaging

How can the Outbox Pattern provide reliable messaging in your microservices?

Kayleigh Kavanagh
The Tech Collective
4 min readMar 26, 2024

--

Photo by Christina Morillo

Recently, I encountered the Outbox Design Pattern for the first time, and I found it insightful. When developing microservices, especially in distributed systems, we must prioritize building applications that can perform reliably. This is where the “Outbox Pattern” comes in, offering a solution to the challenges associated with publishing events in a microservices architecture reliably.

Understand the Outbox Pattern

What is the Outbox Pattern and why do we need it? The use case for when a service needs to perform some action on the database and send events to an Event Stream. However, a single transaction can’t span over a database and event stream.

Say we are working on a system that stores sensitive data into a database and we want to perform some action on this data. Let's consider an example, a financial services company that deals with highly sensitive customer data such as banking transactions. We store these banking transactions in the database, but before we can send the event on the Event stream, the system crashes. Meaning it is only stored in the database, not in the downstream system consuming the stream. And vice versa, if we send an event in the stream, but the system fails before we can commit the database changes, we have inconsistencies. In this example, we leave the system in an inconsistent state. When working with sensitive information we must find a solution that handles this data carefully and ensures it's not lost.

This is where the Outbox Pattern comes in handy as it completely decouples the service from any other services. We don't have to depend on either the Database or Event Steam successfully processing the message.

This pattern ensures a way of reliably publishing messages. It uses a database table, usually referred to as the OUTBOX table as a temporary message queue. When a service performs a transaction, create/update/delete, this will send a message by inserting the update into this Outbox table as part of a single transaction which provides atomicity because of this local ACID transaction.

The message is then picked up by a separate process which then sends the message to the message broker.

The Outbox Pattern consists of the following key components:

  1. Events: Within the application, an event will be produced and stored in the Outbox table.
  2. Outbox table: Stores the messages until they are processed by the message publisher.
  3. Message Publisher: Processes messages from the table and sends them to the relevant destination.

Benefits of using Outbox Pattern

  • Reliable: The pattern ensures messages are delivered, allowing for reliable messaging. You can guarantee that if the database write was successful, the message publisher will certainly publish the message, and can retry for failed deliveries.
  • Scalable: With messages stored in the database, the Outbox Pattern can accommodate high message volumes while maintaining performance. The message broker can consume these messages from the table at a controlled rate.
  • Simple: This method removes the need for complex transactions like two-phase commits (2PC) or coordinating commits using single transactions, simplifying the process and reducing complexity.

Drawbacks of using Outbox Pattern

This pattern solves the initial problem of reliable message delivery. However, it can introduce further problems.

  • Bottleneck: It can turn the system's database into a bottleneck, hindering performance and scalability.
  • Storage overhead: Adds a storage overhead to the system, especially in systems with high message volumes, potentially burdening system resources.
  • Message duplication: There is also the risk of message duplication as the Outbox Pattern provides at-least-once delivery, it does not guarantee exactly-once delivery.

Conclusion

The Outbox Pattern provides an efficient solution to the challenges of asynchronous communication. This pattern ensures reliable message transmission and database updates by decoupling the event stream. This means that even in the event of potential system failures messages are sent reliably and the database is updated consistently. This enhances the robustness and resilience of the application. Moreover, the Outbox Pattern promotes a modular scalable architecture, allowing for easier maintenance and extensibility for future development needs.

--

--