Architecture
Publish / Subscribe
Publishers send messages to a topic on a broker; subscribers listen to topics they care about — neither side ever knows the other exists.
✗ The problem
One producer, calling every consumer directly
Placing an order must notify email, analytics, and the search index. Calling each one by hand couples the order service to all of them — and blocks the request until every call returns.
class OrderService {
placeOrder(order) {
save(order);
email.send(order); // ← coupled
analytics.track(order); // ← coupled
search.index(order); // ← coupled, blocks
}
}
Add a new consumer → edit
OrderService again. One slow consumer
slows down every order.
✓ How it works
↓
↓
Invert it: publish to a topic, let the broker fan out
Publishers send messages to a named topic. Subscribers register on that topic. The broker delivers to everyone subscribed — publisher and subscribers never reference each other.
broker.subscribe(
'order.created', email.send);
broker.subscribe(
'order.created', analytics.track);
broker.publish(
'order.created', order);
// → broker fans out to every
// subscriber of that topic
Publisher
Broker
topic: order.created
Subscriber A
Subscriber B
Compare with Observer: same broadcast
idea, but Observer runs in one process with direct object references. Pub/Sub puts a
broker in between — publishers and subscribers can live in different processes,
even different machines, and only agree on a topic name.
✓ See it live
Publish to a topic — watch the broker fan it out
Publish order.created or payment.failed. Only subscribers on the
matching topic light up. Click a subscriber to unsubscribe it, then publish again.
📡 Broker waiting…
✉️
Email
order.created
—
📊
Analytics
order.created
—
🔎
Search Index
order.created
—
🚨
Fraud Alert
payment.failed
—
0 subscribers notified
✓ Takeaway
Decoupling through a broker
- Decoupling at scale: publishers and subscribers only agree on a topic name, not on each other — they can live in different services, languages, or machines.
- Fan-out: one publish reaches every subscriber of a topic, automatically.
- Add / remove consumers freely: the publisher's code never changes.
- Async: the publisher doesn't wait on subscribers to finish their work.
- Careful: delivery guarantees (at-least-once vs exactly-once), message ordering, and duplicate handling are real design decisions — the broker doesn't solve them for free.
- Seen in: Kafka, Redis Pub/Sub, AWS SNS, MQTT.
🎯 Combines / relates: Pub/Sub is Observer scaled across processes via a broker; underpins event-driven architecture, queues, and event sourcing.
Back to all topics →