</> MAANG.io
system design Β· 201

Intermediate

Master system design interviews with scalable architecture patterns, distributed systems, and real-world design challenges.

0/124 solved 0% complete

Redis Pub/Sub β€” Part 1: Foundations & Core Concepts

maang.io System Design Series


What is this?

Picture an old-fashioned live radio broadcast. A station transmits on a frequency β€” say 98.5 FM β€” and anyone with a radio tuned to that frequency right now hears the song. That's it. The station doesn't know who's listening, doesn't wait for anyone, and doesn't keep a copy. If your radio is switched off when your favourite track plays, you've missed it forever β€” there's no rewind, no "play it again," no recording. The broadcast happened; you either caught it live or you didn't.

That is Redis Pub/Sub almost exactly. A publisher shouts a message onto a named channel; every client currently subscribed to that channel receives it, right then, once. Redis doesn't store the message, doesn't track who missed it, and doesn't retry. It's the purest, lightest form of the publish–subscribe pattern (there's a dedicated topic on that pattern in this tier β€” read it for the general shape) bolted onto a database you probably already run.

The one-line idea: Redis Pub/Sub is a live radio broadcast β€” messages are pushed instantly to whoever is tuned in at that moment, with no persistence and at-most-once delivery. Miss the broadcast (disconnected, slow, or subscribing a second too late) and the message is simply gone.

We'll carry this radio analogy all the way through the internals in Part 2 and the interview in Part 3. Hold onto it: almost every surprising thing about Redis Pub/Sub falls out of "it's a live broadcast, not a recording."


1. Why it exists β€” the problem it solves

You already have Redis in your stack for caching or as a data store (see the Redis topic in this tier). One day you need one service to tell another that something happened β€” "this cache key just changed," "a new chat message arrived," "user 42 came online" β€” without the two services calling each other directly.

Before a broadcast primitive, your options were all clumsy:

  • Polling: every service repeatedly asks "anything new?" β€” wasteful, and always a little stale.
  • Direct calls: the producer opens a connection to each consumer β€” now the producer must know every consumer, and they're tightly coupled.
  • Standing up a message broker (Kafka, RabbitMQ) just to move a tiny "cache changed" ping β€” heavyweight for a fire-and-forget signal.

Redis already holds thousands of open client connections and runs an event loop that can push data to them. So the authors added a dead-simple broadcast layer on top: publishers send to a channel by name, subscribers register interest in a channel by name, and Redis fans each message out to the current subscribers. Producers and consumers never learn about each other β€” they only share a channel name. That decoupling is the whole point of asynchronous messaging (another topic here), and Pub/Sub is its most minimal expression.

πŸ’‘ The killer feature isn't power β€” it's that it's already there and near-instant. If you run Redis, you have a low-latency broadcast bus for free, with no new infrastructure to operate.


2. Core concepts & vocabulary

The whole model is four verbs and one noun. Here's the mental model:

2. Core concepts & vocabulary

  • Channel β€” a named broadcast frequency, e.g. news.sports. It's just a string. Channels are not stored anywhere and don't need to be created; a channel "exists" only in the sense that clients are subscribed to it at this instant. Publish to a channel with zero subscribers and the message evaporates.
  • PUBLISH channel message β€” transmit message on channel. Returns the number of clients that received it (0 if nobody's listening). Fire-and-forget: it returns immediately, having handed the message to whoever was tuned in.
  • SUBSCRIBE channel [channel …] β€” tune this connection into one or more exact channels.
  • PSUBSCRIBE pattern [pattern …] β€” tune into every channel whose name matches a glob-style pattern: news.* catches news.sports and news.weather; user.?? matches two-character suffixes. This is a radio scanner sweeping a whole band instead of one station.
  • UNSUBSCRIBE / PUNSUBSCRIBE β€” tune out.

Two properties define everything downstream:

  1. No persistence. Redis never writes the message down. It's a broadcast, not a mailbox.
  2. At-most-once delivery. Each subscriber gets a given message zero or one time β€” once if it's connected and keeping up, zero times otherwise. Never twice. There are no acknowledgements and no redelivery.

⚠️ One consequence trips up newcomers constantly: a subscriber that isn't connected at the instant of the PUBLISH misses the message permanently. Reconnecting after a network blip, deploying a new version, or even subscribing a millisecond too late means those messages are gone. The radio was playing while your set was off.


3. How you actually use it

The API is so small you can learn it in one screen. Two terminals talking to the same Redis:

# Terminal 1 β€” a subscriber tunes in and then just waits for pushes
redis> SUBSCRIBE chat.room42
1) "subscribe"
2) "chat.room42"
3) (integer) 1
# ... connection now blocks, receiving messages as they arrive ...

# Terminal 2 β€” a publisher broadcasts
redis> PUBLISH chat.room42 "hello everyone"
(integer) 1          # 1 subscriber received it

# Back in Terminal 1, the message arrives, unprompted:
1) "message"
2) "chat.room42"
3) "hello everyone"

Pattern subscription is just as easy β€” one connection can follow a whole family of channels:

redis> PSUBSCRIBE chat.*
# a PUBLISH to chat.room42 now arrives as a "pmessage" carrying BOTH
# the pattern that matched AND the concrete channel:
1) "pmessage"
2) "chat.*"           # the pattern you subscribed with
3) "chat.room42"      # the actual channel it landed on
4) "hello everyone"

⚠️ A subscribed connection is (mostly) a one-way street. Once a client issues SUBSCRIBE, that connection enters subscribe mode and β€” on the classic RESP2 protocol β€” may only issue further subscribe/unsubscribe commands, PING, and QUIT. You can't SUBSCRIBE and run a GET on the same connection. In practice you dedicate one connection to listening and use a separate connection for normal commands (client libraries handle this for you). RESP3 relaxes this by letting server "push" messages interleave with regular replies.


4. When to reach for it β€” and when not

Redis Pub/Sub is the right tool when the message is a live signal and losing an occasional one is survivable:

  • Cache invalidation fan-out β€” one node changes data and broadcasts "drop key X" to every app server's local cache. If a server misses it, its next read just refreshes from the source; low stakes.
  • Live notifications / presence β€” "user came online," "typing…," "new like." Ephemeral by nature; a dropped "typing…" doesn't matter.
  • Chat / room fan-out β€” push a message to everyone currently in a room (often paired with a durable store for history β€” Pub/Sub does the live delivery, a database keeps the record).
  • Real-time dashboards / metrics ticks β€” you always want the latest, not a backlog.

Reach for something else when you need the message to survive:

You need… Don't use Pub/Sub β€” use…
Replay, history, or "process everything that happened while I was down" Redis Streams (a persistent, append-only log with consumer groups + acks) or Kafka
Guaranteed / at-least-once delivery with acknowledgements Streams, Kafka, or a broker like RabbitMQ
Load-balancing work across a pool of workers (each message handled once) Streams consumer groups or a task queue
Durable, replayable event backbone across many teams Apache Kafka (see its topic in this tier)

πŸ’‘ The cleanest way to remember the line: Pub/Sub is a radio broadcast; Redis Streams and Kafka are a DVR. If a subscriber being asleep for five minutes and missing everything is fine, broadcast. If it's a bug, you need a recording. We'll sharpen this Streams-vs-Pub/Sub and Kafka-vs-Pub/Sub comparison with real internals in Part 2 and defend it under interview fire in Part 3.


5. Key takeaways

  1. Redis Pub/Sub is a live broadcast bus: publishers PUBLISH to a named channel, and every client currently SUBSCRIBEd (or matched via PSUBSCRIBE glob patterns) receives it instantly β€” publishers and subscribers never know each other.
  2. No persistence, at-most-once delivery. Redis stores nothing and never retries; a subscriber gets each message zero or one time. Miss the moment (disconnected, deploying, subscribing late) and it's gone for good.
  3. It's free and instant if you already run Redis β€” a low-latency signal bus with no extra infrastructure, ideal for cache invalidation, presence, live notifications, and chat fan-out.
  4. A subscribed connection is dedicated to listening (on RESP2); use a separate connection for normal commands.
  5. Broadcast vs DVR: when losing a message is acceptable, Pub/Sub is perfect; when it isn't, reach for Redis Streams or Apache Kafka instead. Knowing which side of that line you're on is the whole decision.

Next, Part 2 opens the hood: the hash tables and pattern lists Redis keeps in memory, exactly what happens on the single main thread during a PUBLISH, why slow subscribers get disconnected, and how sharded Pub/Sub rescues the model in a Redis Cluster.

Sign in to MAANG.io

Use your Google or Microsoft account β€” no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.