Skip to main content
Redis · lesson 6 of 14
Redis intermediate Lesson 6 of 14

Also part of: Event-Driven Architecture

Pub/Sub: Channels, Patterns, and the Message That Never Arrives

Publishing to a channel with no subscribers doesn't queue the message for later — it's just gone. Real fan-out to multiple subscribers, pattern subscriptions, and sharded Pub/Sub follow.

By SkillByExample · Published

redis pubsub messaging at-most-once

PUBLISH doesn’t put a message in a mailbox — it hands it to whoever happens to be listening at that exact moment, and to no one else.

A message delivered

# subscriber, running in the background
docker exec -i redis-lesson redis-cli SUBSCRIBE news &

# publisher, moments later
docker exec redis-lesson redis-cli PUBLISH news "breaking story"
1

PUBLISH returns 1 — one subscriber received it. The subscriber’s own terminal shows:

subscribe
news
1
message
news
breaking story

The subscribe confirmation comes first (channel name, then the count of channels this client is now subscribed to), followed by the actual message when one arrives: type, channel, payload.

The bug: publishing to no one

docker exec redis-lesson redis-cli PUBLISH nobody-listening "hello?"
0

0 — not an error, just nobody home. The message isn’t queued anywhere waiting for a future subscriber; it’s gone the instant PUBLISH returns. Someone expecting SUBSCRIBE nobody-listening a minute later to receive this message will wait forever — Pub/Sub has no concept of “catch up on what I missed.” When messages must survive until someone reads them, use a stream instead: Streams and Consumer Groups repeats this experiment with XADD.

Fan-out: every subscriber gets a copy

docker exec -i redis-lesson redis-cli SUBSCRIBE alerts &   # subscriber 1
docker exec -i redis-lesson redis-cli SUBSCRIBE alerts &   # subscriber 2
docker exec redis-lesson redis-cli PUBLISH alerts "server down"
2

Both subscribers’ terminals show the identical message alerts "server down" — PUBLISH broadcasts to every current subscriber of the channel, not to just one of them. There’s no partitioning here; every listener gets every message.

Pattern subscriptions

docker exec -i redis-lesson redis-cli PSUBSCRIBE "news.*" &
docker exec redis-lesson redis-cli PUBLISH news.tech "new phone"
docker exec redis-lesson redis-cli PUBLISH news.sports "big game"
docker exec redis-lesson redis-cli PUBLISH other "irrelevant"
1
1
0

The pattern subscriber received both news.tech and news.sports — its terminal shows two pmessage entries (pattern, channel, payload) — but the other channel doesn’t match news.*, so PUBLISH other correctly returned 0: that pattern subscriber was never a candidate for it.

Sharded Pub/Sub

docker exec -i redis-lesson redis-cli SSUBSCRIBE shard-channel &
docker exec redis-lesson redis-cli SPUBLISH shard-channel "sharded hello"
1

Same behavior as regular Pub/Sub on this single instance — SSUBSCRIBE/SPUBLISH only show their real purpose on a Redis Cluster, where a shard channel is hashed to a slot the same way a key is, so its traffic stays within that channel’s shard instead of crossing the whole cluster.

Practice

1. Subscribe to a channel, then list every active channel from another connection.
docker exec -i redis-lesson redis-cli SUBSCRIBE watch-channel &
docker exec redis-lesson redis-cli PUBSUB CHANNELS
docker exec redis-lesson redis-cli PUBSUB NUMSUB watch-channel
watch-channel
watch-channel
1

PUBSUB CHANNELS lists every channel with at least one active subscriber — useful for debugging “is anyone actually listening” without needing your own test subscriber. PUBSUB NUMSUB returns channel-count pairs, here showing exactly one subscriber on watch-channel.

2. Force-disconnect every Pub/Sub client and confirm the channel list empties.
docker exec redis-lesson redis-cli CLIENT KILL TYPE pubsub
docker exec redis-lesson redis-cli PUBSUB CHANNELS
1

CLIENT KILL TYPE pubsub disconnects every client currently in subscriber mode — 1 here means one connection was closed — and PUBSUB CHANNELS afterward returns nothing at all, since there’s no one left subscribed to anything.

3. Subscribe to multiple channels in one call and confirm both confirmations arrive.
docker exec -i redis-lesson redis-cli SUBSCRIBE first second
subscribe
first
1
subscribe
second
2

One SUBSCRIBE call can list several channels — each gets its own subscribe confirmation, and the count in the third field is the running total of channels this connection is now subscribed to (1, then 2), not a per-channel count.

Next: persistence — RDB snapshots, the append-only file, and the new BACKUP command family.

Frequently Asked Questions

What does PUBLISH's return value mean?
The number of subscribers that actually received the message at that instant — not whether it was queued, stored, or will be delivered later. A 0 means no one was listening when it was published, and that message is gone; it will never be delivered to a client that subscribes afterward.
Why is this called at-most-once delivery?
A message is delivered zero times (nobody was subscribed, or a subscriber's connection dropped before receiving it) or exactly once — never queued for retry, never redelivered. Contrast this with Redis Streams (see the Streams and consumer groups lesson later in this track), which persist messages and support at-least-once delivery through consumer groups that track what's been acknowledged.
What's the difference between message and pmessage in the reply format?
A plain SUBSCRIBE gets message replies: type, channel, payload. A PSUBSCRIBE (pattern) gets pmessage replies with one extra field: type, the pattern that matched, the actual channel, payload. Client libraries usually hide this distinction behind one callback, but at the protocol level they're genuinely different reply shapes.
Does sharded Pub/Sub (SSUBSCRIBE/SPUBLISH) require a cluster to work?
No — it works identically on a single standalone instance, just without the benefit it exists for. In a real Redis Cluster, sharded channels are assigned to hash slots the same way keys are, so message traffic for one channel only crosses the nodes in that channel's shard instead of every node in the cluster. On one instance there's only one shard, so the behavior looks the same as regular Pub/Sub.
Can two different subscribers to the same channel receive different copies of a message?
No — PUBLISH broadcasts to every current subscriber of that exact channel (or every pattern subscriber whose pattern matches), and each one gets the identical payload. There's no partitioning or load-balancing across subscribers to a plain channel; if you want work distributed across consumers instead of broadcast to all of them, that's what Streams' consumer groups are for.