Two Ways to Move Messages
A voice recorder saves everything. You can play it back later, from any point, as many times as you like. That is a Redis stream.
Both send messages to listeners. The difference is memory: Pub/Sub forgets the instant it sends; a stream remembers. This tutorial shows how each works and how to pick.
Pub/Sub — Broadcast to Many Clients
Pub/Sub (publish / subscribe) sends a message to every client listening on a channel, at the
same moment. A publisher sends with PUBLISH. Listeners join a channel with
SUBSCRIBE. One message reaches all of them — a fan-out.
One PUBLISH to a channel is delivered to every current subscriber at once. The
reply tells you how many received it.
# terminal 1: listen on a channel (this connection now waits for messages)
SUBSCRIBE news
# terminal 2: send a message to that channel
PUBLISH news "market opens at 9am"
# -> (integer) 3 the number of subscribers that got it
Once a connection runs SUBSCRIBE, it can only handle messages — it cannot
run normal commands like GET. Use a separate, dedicated connection for
subscribing, and keep your normal commands on another connection.
Pattern Subscribe — One Rule, Many Channels
You do not have to name every channel. PSUBSCRIBE uses a pattern, so one subscriber
can catch many related channels at once. A rule like order.* matches
order.created, order.paid, and order.shipped.
A pattern subscriber receives from every channel that matches. Channels that do not match are ignored.
# subscribe to every channel that starts with "order."
PSUBSCRIBE order.*
# any of these now reach the subscriber
PUBLISH order.created "#9001"
PUBLISH order.paid "#9001"
# this one does NOT match order.* so it is not delivered
PUBLISH user.login "user 57"
| Command | What it does |
|---|---|
SUBSCRIBE ch | Listen on one or more channels |
PUBLISH ch msg | Send a message; returns how many got it |
PSUBSCRIBE pattern | Listen on all channels matching a pattern |
UNSUBSCRIBE / PUNSUBSCRIBE | Stop listening |
The Catch — Pub/Sub Is Fire-and-Forget
Pub/Sub is fast and simple, but it has no memory. A message is sent to whoever is listening at that instant, and then it is gone. Know these three limits before you rely on it.
Fire-and-forget is perfect when only "right now" matters: a typing indicator, a live score, a "someone just joined" ping, or telling all your app servers to clear a cache. If missing a message is harmless, Pub/Sub is the simplest tool.
Streams vs Pub/Sub — The Key Difference
A stream is an append-only log. Every message is stored with an ID, so a reader can come back later and read from where it left off. This one difference — memory — decides most choices between the two.
Left: Pub/Sub delivers live; an offline listener misses the message forever. Right: a stream stores it, so a reader that was offline catches up when it returns.
| Live delivery only |
| Offline listeners miss it |
| No history, no replay |
| No acknowledgement |
| Simplest to set up |
| Stored with IDs |
| Late readers catch up |
| Replay any time |
| Consumer groups + XACK |
| A bit more to manage |
| Point | Pub/Sub | Stream |
|---|---|---|
| Stores messages? | No | Yes |
| Offline reader catches up? | No | Yes |
| Replay old messages? | No | Yes |
| Delivery guarantee | At most once | At least once (with XACK) |
| Share work across workers | All get every message | Consumer groups split it |
| Memory use | Tiny (nothing kept) | Grows — cap with MAXLEN |
| Setup effort | Lowest | A little more |
Which One Should You Pick?
Ask one question: "If a listener is offline for a second, is it OK to miss this message?" If yes, use Pub/Sub. If no, use a stream. When in doubt, a stream is the safer choice because it keeps the message.
Golden Rules
SUBSCRIBE connection
can only receive messages, not run normal commands. Keep the two apart.
order.* catches many related channels without naming each one.