What is the Asynchronous Messaging pattern?
Producers send messages to a queue or publish them to a topic, and consumers process them on their own schedule. A command goes to one receiver and asks for something to be done. An event announces a fact and can have any number of subscribers.
What problem does the Asynchronous Messaging pattern solve?
A chain of synchronous calls ties your availability and latency to every service in the chain. Messaging decouples services in time, absorbs traffic spikes in a queue and makes fan-out easy.
How do you implement the Asynchronous Messaging pattern?
- Decide what is a command (one receiver, asks for an action) and what is an event (a fact, many subscribers).
- Pick broker semantics you need: ordering, retention, delivery guarantees and replay.
- Make consumers idempotent and send poison messages to a dead-letter queue.
- Version message schemas and keep changes backward compatible.
- Propagate trace context in message headers and alert on consumer lag.
When should you use it?
- The caller does not need the answer right now.
- Work arrives in bursts, or one change must notify several services.
When should you avoid it?
- The caller needs an immediate answer, such as a price lookup during checkout.
- A tiny system where a broker costs more to run than it saves.
What do you gain?
- Decoupled in time and availability
- Buffers spikes
- Easy fan-out to new consumers
What does it cost?
- Eventual consistency
- Harder to debug and test
- At-least-once delivery means duplicates
- The broker becomes critical infrastructure
What are common mistakes with the Asynchronous Messaging pattern?
- Using messages as disguised remote calls and then waiting for the reply.
- No dead-letter queue, so one bad message blocks a partition.
- Consumers that assume global ordering.
Asynchronous Messaging in practice
Marlow Market
Checkout called the email, loyalty and audit services synchronously. When the email provider slowed down, checkout slowed down with it.
Checkout now publishes an OrderPlaced event and returns. Email, loyalty and audit subscribe to it and catch up on their own, so a slow subscriber no longer affects checkout.
Example decision record
- Context
- Notifications and audit logging are called synchronously and add latency to checkout.
- Decision
- Publish an event after checkout and move notifications and audit to subscribers.
- Consequences
- A slow or failing subscriber no longer slows or fails checkout.
- Notifications become eventually consistent and need monitoring for consumer lag.