Redis Pub/Sub vs Streams: Two Tools That Look Similar and Solve Opposite Problems
January 16, 2026
These two Redis features live in the same product and share the word "message," and that is where the confusion ends. Pub/Sub and Streams answer different questions, and the wrong choice silently corrupts your system until the day it bites.
Pub/Sub is fire and forget. A publisher calls PUBLISH channel payload. Redis pushes the payload to every connected subscriber on that channel right now. There is no log. There is no offset. There is no retry. If a subscriber is offline, busy, or behind on its socket buffer, the message goes to the floor. Redis does not remember it ever existed. Pub/Sub answers exactly one question: "who is listening to this channel at this instant?"
That is fine for some things. Live dashboards. WebSocket fan-out where a missed tick is replaced by the next tick a second later. Cache invalidation, where worst case the cache TTL bails you out. Anything where missing a message is annoying but not wrong.
Streams are the other shape. XADD appends an entry to a durable log. Entries get monotonic IDs and survive restarts as long as RDB or AOF is on. Consumers join a group with XREADGROUP. Each consumer in the group gets a partition of the work, every delivered entry sits in the Pending Entries List until XACK, and if a consumer crashes mid-process, another consumer can XCLAIM the entry after the idle timeout. You also get replay: read from any ID, including the start of the stream, and process history.
The migration story I have seen at least four times. A team ships v1 with Pub/Sub because it is one line of code. Things work great in development, where the subscriber is always running. Production hits the first network blip. Subscriber drops for two seconds. Three hundred messages vanish. Nobody notices until a customer reports their order never processed. Now there is no log to look at, because Pub/Sub never wrote one. The fix is to migrate to Streams, but the team also has to backfill the lost state from somewhere else, which is the part that hurts.
Mental model. Pub/Sub is a live broadcast on a radio. If your receiver is off, the show happened anyway. Streams are a recorded show with bookmarks. You can join late, you can rewind, and the studio knows whether each viewer watched the episode.
Pick Pub/Sub for ephemeral signals where loss is acceptable. Pick Streams for jobs, events, and workflows where loss is not. If you cannot articulate which side of that line you are on, default to Streams.
Pub/Sub answers who is listening right now. Streams answer what happened and who processed it. If you cannot afford to lose a message, you cannot use Pub/Sub, no matter how convenient it looks.
Originally posted on LinkedIn. View original.