Explainstuff.mebeta
All concepts
Messagingintermediate8 min

Pub/Sub Messaging

Broadcast an event once and let any number of interested services react to it — without the sender ever knowing they exist.

When something happens in a system — an order is placed, a user signs up, a file is uploaded — several other parts often need to react. The order should be charged, a confirmation email sent, inventory updated, and analytics recorded.

Publish/subscribe (Pub/Sub) is a messaging pattern that lets the part where the event happened announce it once, and lets every interested part react independently — without any of them having to know about each other.

The problem: one service calling many others

The naive approach is to have the order service call each downstream service directly: charge the card, then call the email service, then the inventory service, then analytics. Every call is synchronous, so the order isn't done until the slowest of them responds — and if any one is down, the whole flow can fail.

Worse, the order service now knows about all four collaborators. The day you want to add a fraud-detection step, you have to open the order service and change it. This is tight coupling: the producer of the event carries the burden of knowing every consumer, and the list of consumers leaks into code that has nothing to do with consuming.

How it works

Pub/Sub puts a broker in the middle. Instead of calling anyone, the order service publishes a single message — say OrderPlaced — to a named topic on the broker. It doesn't address any recipient; it just hands the message over and moves on.

The interested services have each subscribed to that topic ahead of time. The broker takes the one published message and delivers a copy to every subscriber — the email service, the inventory service, and analytics all receive their own copy at roughly the same time, and each processes it on its own schedule. The publisher never learns who they are or how many there are; the subscribers never know who sent it. That mutual ignorance is the whole point — it's what decouples them.

One message, many subscribers
message
Producer
Topic
Subscriber A
Subscriber B
Subscriber C
A producer publishes one message; the broker delivers a copy to every subscriber.
Tip

Adding a consumer is now free for the producer. To introduce fraud detection, you just write a new service that subscribes to the OrderPlaced topic. The order service doesn't change — it's still publishing the same single message. This is the payoff of decoupling: you extend the system by adding subscribers at the edges, not by editing the code at the center.

Delivery guarantees and semantics

Decoupling buys flexibility, but it forces you to think about what "delivery" actually promises:

  • At-least-once delivery — most brokers guarantee a message arrives at least once, but to survive crashes and retries they may deliver it more than once. Consumers must therefore be idempotent: processing the same message twice should have the same effect as processing it once (e.g. key the email send on the order ID so a duplicate is a no-op).
  • Ordering — within a single topic you often can't assume messages arrive in the order they were published, especially once delivery is parallelized. If order matters, you usually need a partition or ordering key so related messages travel the same path.
  • Fan-out vs. consumer groupsfan-out means every subscriber gets its own copy of every message (email, inventory, and analytics each see all orders). A consumer group is different: several instances of one service share a subscription so each message goes to only one instance — that's how you scale a single subscriber horizontally, much like load balancing spreads work across servers.

The trade-offs

Pub/Sub is not free:

  • Eventual consistency — because subscribers process asynchronously, there's a window where the order exists but the confirmation email hasn't sent and inventory hasn't updated. The system converges to a correct state, but not instantly.
  • Harder debugging and observability — there's no single call stack to follow. A request fans out into independent flows, so tracing "what happened to order #123" means correlating logs across several services and the broker. Distributed tracing and correlation IDs become essential rather than optional.
  • Duplicates and ordering land on you — the at-least-once and unordered semantics above mean every consumer has to be written defensively, which is real engineering effort.
  • The broker is critical infrastructure — you've concentrated all communication through one component. If the broker is down or backed up, nothing gets delivered, so it has to be highly available, monitored, and capacity-planned with care.
Watch out

Asynchronous does not mean fire-and-forget-and-stop-caring. Messages can pile up faster than subscribers can drain them, and a consumer that keeps failing will see the same message redelivered forever. Watch consumer lag (how far behind subscribers are) and route messages that fail repeatedly to a dead-letter queue so one poison message can't block the rest.

When to reach for it

Pub/Sub shines when a single event has many independent reactions, when you want to add or remove consumers without touching the producer, and when those reactions can happen asynchronously rather than blocking the original request. Event-driven architectures, decoupling microservices, and broadcasting state changes are all natural fits.

It's the wrong tool when the caller genuinely needs an immediate answer — a synchronous request/response is simpler and clearer there. And like caching, it's a trade: you give up the simplicity of a direct call and strict consistency in exchange for decoupling, scalability, and resilience to slow or failing consumers.

Key takeaways

  • Pub/Sub decouples producers from consumers: a publisher emits a message to a topic and never knows who, if anyone, receives it.
  • A broker fans out each message to all interested subscribers, turning one publish into one-to-many delivery.
  • Communication is asynchronous — the publisher returns immediately and subscribers process in their own time.
  • Most brokers offer at-least-once delivery, so consumers must be idempotent to tolerate duplicates and may not see strict ordering.
  • Reach for Pub/Sub when one event has many independent reactions and you want to add consumers without touching the producer.

Keep going