Topic 5.1
Pub/Sub: Real-Time, At-Most-Once Messaging
In one line
PUBLISH sends a message to every client currently subscribed to a channel, and then forgets it. It's ideal for live notifications and cache invalidation broadcasts, and wrong for anything that must survive a disconnect, because there's no storage, no acknowledgement and no replay.
Think of it like this
A radio broadcast. Everyone tuned in right now hears the announcement. If your radio was off, or you drove through a tunnel, you missed it, and there's no recording to replay.
Key ideas
- 01
Commands:
PUBLISH channel message(returns how many subscribers received it on this node),SUBSCRIBE ch...,PSUBSCRIBE pattern...(glob patterns likeorders.*),UNSUBSCRIBE,PUNSUBSCRIBE, and introspection withPUBSUB CHANNELS,PUBSUB NUMSUB,PUBSUB NUMPAT. - 02
Delivery is at-most-once: messages go straight from the publisher's command into each subscriber's output buffer. A subscriber that's disconnected, restarting, or too slow (hitting
client-output-buffer-limit pubsub 32mb 8mb 60) loses messages silently. Nothing is persisted or replicated to the AOF. - 03
A RESP2 connection in subscribe mode can only run subscribe-related commands and
PING; use a dedicated connection for subscriptions. With RESP3, push messages share the connection with normal commands. - 04
In Redis Cluster, classic
PUBLISHis broadcast to every node over the cluster bus, so every node pays for every message; it doesn't scale with more shards. Sharded Pub/Sub (Redis 7.0+:SPUBLISH,SSUBSCRIBE) maps each channel to a slot like a key, so traffic is handled only by the shard (and its replicas) that owns the channel. - 05
Good uses: live UI updates (typing indicators, order status pushes), broadcasting cache invalidations to app instances, fan-out between WebSocket servers, and lightweight signalling. Bad uses: anything a consumer must not miss, work queues, audit events.
Code & diagrams
# Terminal 1
127.0.0.1:6379> SUBSCRIBE order-status
1) "subscribe"
2) "order-status"
3) (integer) 1
# Terminal 2
127.0.0.1:6379> PSUBSCRIBE order-*
# Terminal 3
127.0.0.1:6379> PUBLISH order-status '{"orderId":9,"status":"SHIPPED"}'
(integer) 2 # delivered to 2 subscribers on this node
# Terminal 1 receives:
1) "message"
2) "order-status"
3) "{\"orderId\":9,\"status\":\"SHIPPED\"}"
# If nobody is subscribed:
127.0.0.1:6379> PUBLISH nobody-listening hello
(integer) 0 # the message is simply gone
# Cluster: sharded Pub/Sub routes by the channel's slot
127.0.0.1:6379> SPUBLISH {user:42}:notify "you have mail"Interview problem
The problem
Real-time order notifications
Order status changes are published through Redis Pub/Sub to three WebSocket servers, which push them to connected browsers. What happens if WebSocket server 2 is disconnected from Redis for 10 seconds? How would you make notifications reliable?
You're given
- 3 WebSocket servers
- Users connected to any server
- Notifications must eventually reach the user
The interviewer follows up
Does Pub/Sub scale in Redis Cluster?
When it breaks
A subscriber is slower than the publish rate
What you see
Its output buffer grows until it hits the pubsub limit; Redis disconnects it, and everything published while it reconnects is lost.
Fix & prevent
Make consumers fast (hand off work to an internal queue), shard channels, or use Streams where slow consumers just fall behind instead of losing data.
Cache invalidation via Pub/Sub only
What you see
An app instance that was restarting misses an invalidation and serves stale data until the entry's TTL expires.
Fix & prevent
Always keep TTLs on locally cached entries as a backstop; on reconnect, flush the local cache.
Explain it without notes
Why is Pub/Sub at-most-once?
How does sharded Pub/Sub differ from classic Pub/Sub in a cluster?
Practice
Subscribe in one terminal, publish in another, then kill the subscriber, publish 5 messages, and reconnect. What do you see?
Trade-offs
- ↔
Pub/Sub has the lowest latency and zero storage cost, and no delivery guarantees.
- ↔
Sharded Pub/Sub scales in Cluster but needs cluster-aware clients and slot-friendly channel names.
Done when you can
I can explain at-most-once delivery and the output-buffer disconnect.
I can make a real-time notification system reliable with a durable log plus Pub/Sub.
I know when to use
SPUBLISHinstead ofPUBLISH.