In Redis Cluster, how does a message sent with PUBLISH reach subscribers on other nodes, why does that become a scaling problem, and what do SPUBLISH and SSUBSCRIBE do differently?
answer
- Channel has no slot, so classic PUBLISH broadcasts on the cluster bus
- Cost O(nodes) per message, grows with cluster size
- 7.0 shard channels hashed like keys
- SSUBSCRIBE on wrong node returns MOVED
- Separate namespace: SUBSCRIBE never sees SPUBLISH
basics
~20 sClassic PUBLISH is broadcast to every node over the cluster bus so any subscriber anywhere receives it, which makes pub/sub traffic grow with cluster size and never shard. Sharded pub/sub (Redis 7.0) hashes the channel name to a slot: SPUBLISH goes only to that shard's primary and replicas, and SSUBSCRIBE must target that node.
solid answer
~50 sIn cluster mode a client may subscribe on any node, so Redis makes classic PUBLISH work by broadcasting each message across the cluster bus to every other node, which then delivers it to its local subscribers. Correctness is easy, but the cost is O(number of nodes) internal traffic per message regardless of where subscribers actually are. Adding nodes therefore increases pub/sub overhead instead of dividing it, and the bus can saturate long before the keyspace is stressed. Redis 7.0 added sharded pub/sub. A shard channel name is hashed exactly like a key, so it belongs to a hash slot and hence to one shard. `SPUBLISH` sends the message only to that shard's primary and its replicas; `SSUBSCRIBE` must be issued on a node serving that slot or you get a MOVED redirect. Now pub/sub load scales with the cluster. The cost is that clients must be slot-aware and shard channels live in a separate namespace: SUBSCRIBE will not see SPUBLISH messages, and vice versa.
code
text · 17 lines# classic: reaches subscribers on every node, via the cluster bus
> PUBLISH global:config-changed "v2"
(integer) 3
# sharded: slot-bound, stays inside one shard
> CLUSTER KEYSLOT room:42:events
(integer) 9128
> SSUBSCRIBE room:42:events # sent to a node not serving slot 9128
(error) MOVED 9128 10.0.0.5:6379
# on the owning node
> SSUBSCRIBE room:42:events
1) "ssubscribe" 2) "room:42:events" 3) (integer) 1
> SPUBLISH room:42:events "hi"
(integer) 1
> PUBSUB SHARDCHANNELS
1) "room:42:events"go deeper
Recall that in a cluster an ordinary PUBLISH is broadcast to all nodes, so subscribers anywhere receive it.
Explain the cost of that broadcast and that Redis 7.0 shard channels are hashed to a slot so SPUBLISH stays inside one shard.
Discuss cluster-bus saturation and its interaction with gossip/failover traffic, MOVED handling for SSUBSCRIBE, hash tags, and the separate namespace as a migration hazard.
Treat it as a fan-out topology decision: broadcast gives location transparency at O(nodes) cost, sharding gives linear scaling at the price of consumer-side topology awareness, so choose per event class and design channel names so entity scoping is possible.
## Why classic PUBLISH broadcasts Redis Cluster partitions the keyspace into 16384 hash slots spread across shards, but a Pub/Sub channel is not a key and has no slot. A client can subscribe on any node, and the cluster promises that a message published anywhere reaches every subscriber. The only way to keep that promise without a directory of subscribers is to broadcast: on `PUBLISH`, the receiving node delivers to its own subscribers and forwards the message over the cluster bus to all other nodes, each of which delivers locally. ## The scaling problem That design makes pub/sub cost independent of where subscribers are and proportional to cluster size. Every message crosses the bus to every node, including nodes with zero subscribers for that channel, and replicas receive it too. A 20-node cluster amplifies each publish roughly twentyfold in internal traffic. The consequences are practical: the cluster bus is also how nodes gossip health and run failover votes, so heavy pub/sub can add latency to, or interfere with, cluster management traffic. Worst of all, the usual remedy for load, adding nodes, makes it worse, because sharding the keyspace does nothing to shard the broadcast. ## What sharded pub/sub changes Redis 7.0 introduced `SPUBLISH`, `SSUBSCRIBE` and `SUNSUBSCRIBE`. A shard channel name is hashed with the same CRC16 function used for keys, giving it a slot and therefore an owning shard. `SPUBLISH` delivers only within that shard: the primary owning the slot plus its replicas. No cross-shard bus traffic occurs at all. Because subscribers are now tied to a shard, `SSUBSCRIBE` must be sent to a node serving that slot; issuing it elsewhere returns a MOVED redirect, which cluster-aware clients follow like they do for keys. Hash tags work the same way, so `SPUBLISH {user123}:events` co-locates the channel with that user's keys. ## The trade you are making Sharded pub/sub buys horizontal scalability and gives up global reach. The two namespaces are separate: a plain `SUBSCRIBE ch` will never receive a message sent with `SPUBLISH ch`, and `PUBSUB SHARDCHANNELS` / `PUBSUB SHARDNUMSUB` are the introspection commands, distinct from `PUBSUB CHANNELS`. A consumer that must see all events for all entities now has to subscribe on every shard, so the application takes on the fan-out logic that the cluster bus used to do for free. Your client library must support it; older or simpler clients only speak classic pub/sub. A further consequence is failover behaviour. Shard channel subscribers are attached to a specific shard, so when that shard fails over, those subscribers are disconnected and must resubscribe to the new primary, at which point the usual at-most-once gap applies. With classic pub/sub the same gap exists but the client can reconnect to any node. ## Choosing between them Use classic PUBLISH when volume is low and the fan-out is genuinely global, for example a rare cluster-wide configuration invalidation. Use sharded pub/sub when message rates are meaningful and messages are naturally scoped to an entity (a user, a room, a tenant), because hashing that entity into the channel name lets traffic stay inside one shard and lets the cluster grow. In both cases the delivery guarantee is unchanged: still fire-and-forget, still no persistence, still lost for a subscriber that is not connected.
- You need every application node to learn about a change, but message volume is high. How do you use sharded pub/sub without losing global reach?Either accept classic PUBLISH for the rare truly-global events and keep the high-volume ones sharded by entity, or have each consumer open one shard subscription per shard so the application performs the fan-out explicitly. The second option scales because the traffic per shard is bounded, but it makes consumers cluster-topology aware and they must resubscribe when slots move.
- Does a message published with SPUBLISH reach the replicas of the owning shard?Yes. Sharded pub/sub delivers within the whole shard, so subscribers attached to a replica of the slot owner receive it, which is what makes read-scaled subscriber deployments possible. What it does not do is cross to other shards, so subscribers elsewhere in the cluster see nothing.
saying these in an interview costs you the question
- Assuming classic PUBLISH in cluster mode only reaches the node you published on
- Thinking a channel name is hashed to a slot in classic pub/sub
- Believing SUBSCRIBE and SSUBSCRIBE share one namespace
- Claiming sharded pub/sub adds durability or acknowledgements
- Expecting SSUBSCRIBE to work on any node without following MOVED