Publish-subscribe, usually shortened to pub/sub, is a messaging pattern where senders (publishers) broadcast to a named channel (a topic) without knowing who, if anyone, is listening, and receivers (subscribers) register interest in a topic without knowing who publishes to it. Neither side holds a reference to the other. That single design choice — routing through a topic instead of a direct address — is what lets the same idea scale from a single function call inside one process to a cluster handling millions of events a second.
What changed in 2026
- Serverless pub/sub became the default for small teams. Cloudflare Queues, Supabase Realtime, and similar managed primitives let teams add topic-based messaging without standing up a broker.
- Browser-native options matured. BroadcastChannel and Server-Sent Events now cover many cross-tab and simple real-time cases that used to reach straight for a full WebSocket setup.
- Multi-agent AI systems adopted pub/sub for coordination. Frameworks running several AI agents concurrently increasingly use an internal event bus so agents react to each other without being wired together directly.
Publisher, subscriber, topic
A publisher sends a message tagged with a topic and moves on; it does not wait for anyone to read it. A subscriber registers interest in a topic and receives every message published to it from then on. The topic is the only thing connecting them — swap out every subscriber, add ten more, or remove them all, and the code on the publisher side does not change.
This produces decoupling along two axes that matter: neither side needs the other address or identity, and a publisher does not block waiting for a subscriber to finish — a natural fit for anything that should not slow down the sender.
Where the pattern shows up
Pub/sub is not one technology; it is a shape that recurs at every layer of a system.
| Layer |
Example technology |
Delivery scope |
| In-process |
EventEmitter, signals, RxJS Subjects |
Same process only |
| Browser |
DOM events, BroadcastChannel, SSE |
Same tab or same-origin tabs |
| Real-time app |
WebSocket fan-out, Redis Pub/Sub, Pusher-style services |
Currently connected clients |
| Mobile push |
FCM topics, APNs topics |
Subscribed devices, queued while offline |
| Backend infra |
Kafka topics, Google Pub/Sub, AWS SNS, MQTT |
Cross-service, often durable |
The properties change a lot down that table — an in-process emitter has zero persistence; a Kafka topic can retain messages for days and replay them to a brand-new subscriber. What stays constant is the shape.
Pub/sub versus the alternatives
A point-to-point queue delivers each message to exactly one consumer, for distributing work, not broadcasting an event. A direct API call or RPC expects a reply and couples the caller to a specific address, which pub/sub deliberately avoids. The observer pattern is the closest relative, but classic observer usually has the subject holding direct references to its observers, while pub/sub routes through an intermediary so the two sides often never know about each other at all. When that intermediary becomes real infrastructure, you are looking at a message broker.
A minimal implementation
The core idea fits in a few lines, backed by nothing more than an array:
class Topic {
subscribers = [];
subscribe(fn) { this.subscribers.push(fn); }
publish(message) { this.subscribers.forEach(fn => fn(message)); }
}
const orders = new Topic();
orders.subscribe(order => sendReceipt(order));
orders.subscribe(order => updateInventory(order));
orders.publish({ id: 42, total: 19.99 });
Redis gives the same shape across processes with two commands: SUBSCRIBE orders and PUBLISH orders '{"id": 42}'. Neither example has persistence, replay, or delivery guarantees — that is the honest baseline of pub/sub. Anything beyond that is a feature of the broker layered on top, not the pattern itself.
Common pitfalls
- Assuming delivery guarantees you do not have. Plain pub/sub (an event emitter, browser events, basic Redis pub/sub) is fire-and-forget: if no subscriber is listening at publish time, the message is gone. Durable delivery and replay require a broker built for it, covered in more depth in event-driven architecture.
- Topic sprawl with no ownership. A topic per event type sounds clean until there are hundreds of them and no one can say who owns which. Name and document topics deliberately.
- Using pub/sub where a reply is actually needed. If the publisher needs to know the outcome, it is describing a request-response interaction, not an event, and forcing it into pub/sub adds indirection without benefit.
FAQ
Is publish-subscribe the same as a message queue?
No. A queue delivers each message to exactly one consumer, for splitting up work. Pub/sub delivers each message to every current subscriber, for broadcasting an event to however many interested parties exist.
Do I need a message broker to use publish-subscribe?
No. Pub/sub is a pattern, not a product. An in-process event emitter is pub/sub. A broker is what you reach for once you need the pattern to work across services, processes, or machines, with durability guarantees.
Can a subscriber miss a message?
Depends on the implementation. Basic pub/sub (browser events, a plain event emitter, unbuffered Redis channels) delivers only to subscribers connected at publish time. Brokers with persistence and consumer offsets, like Kafka, let a subscriber catch up on messages published before it connected.
How is pub/sub different from webhooks?
A webhook is typically one publisher calling one known URL directly, closer to point-to-point than broadcast. Pub/sub decouples the publisher from knowing who or how many receivers exist at all.
Where to go next