Pub/Sub

intermediate redis pubsub messaging

Pub/Sub is Redis’s built-in messaging system. Publishers shout into a channel, subscribers listening on that channel receive the message. No queue, no persistence — if you’re not listening when a message is published, you miss it forever.

In simple language: it’s like a radio broadcast. The DJ plays a song. If your radio is on, you hear it. If it’s off, tough luck — there’s no replay.

Why use it?

Real-time fanout where missing a message is acceptable:

  • Cache invalidation across app servers (“user:123 changed, drop your cached copy”)
  • Live notifications (someone liked your post)
  • Chat rooms with no history requirement
  • Triggering refreshes on a dashboard

Pub/Sub trades durability for simplicity and speed.

The commands

# Terminal 1 - subscriber
SUBSCRIBE news.tech news.sports

# Terminal 2 - publisher
PUBLISH news.tech "Redis 8 released"
# returns the number of subscribers that received it

Pattern subscription with PSUBSCRIBE uses glob-style wildcards:

PSUBSCRIBE news.*       # matches news.tech, news.sports, anything
PSUBSCRIBE order.*.paid # matches order.123.paid

Fanout in one picture

Publisher
PUBLISH news.tech "..." →
Channel: news.tech
↓ fanout to all live subscribers ↓
Subscriber A
Subscriber B
Subscriber C
Subscriber D (offline) — misses the message forever

The catch: fire-and-forget

Redis Pub/Sub has at-most-once delivery:

  • No persistence — messages live only in memory during delivery
  • No acknowledgments — Redis doesn’t care if you actually processed it
  • No replay — disconnected subscribers can’t catch up
  • Slow subscribers get disconnected (Redis won’t buffer indefinitely)

If your subscriber crashes mid-message, that message is gone.

Pub/Sub vs Streams

Streams (XADD/XREAD) were added precisely because Pub/Sub couldn’t handle durable messaging.

FeaturePub/SubStreams
PersistenceNoYes (in-memory + AOF/RDB)
ReplayNoYes, by ID
Consumer groupsNoYes (Kafka-like)
AcknowledgmentsNoYes (XACK)
DeliveryAt-most-onceAt-least-once
Use caseLive fanoutEvent sourcing, work queues

Rule of thumb: if missing a message is a bug, use Streams. If missing a message is fine, Pub/Sub is simpler and faster.

Real-world example: cache invalidation

// Publisher (after DB write)
await db.update("users", { id: 123, name: "Manish" });
await redis.publish("cache.invalidate", "user:123");

// Subscriber (every app server)
sub.subscribe("cache.invalidate");
sub.on("message", (channel, key) => {
  localCache.delete(key);
});

Every app server clears its in-memory cache the moment the DB changes. If a server happens to be restarting and misses the message, no big deal — its cache is empty anyway.

Gotchas

  • Subscribed clients can’t issue normal commands (the connection is in subscribe mode). Use a separate connection for publishing.
  • PSUBSCRIBE is slower than SUBSCRIBE — Redis runs glob matching per channel per pattern.
  • In Cluster mode, regular Pub/Sub broadcasts cluster-wide. Sharded Pub/Sub (SSUBSCRIBE, Redis 7+) scopes channels to shards for better scalability.