Modern applications increasingly rely on event-driven architecture to communicate between services, process background tasks, deliver notifications, and handle real-time updates.
If you are already using Redis, two features often come up when designing these systems:
Redis Pub/Sub and Redis Streams.
At first glance, they may appear to solve the same problem. Both allow producers to send events that other parts of an application can consume.
But their behavior is fundamentally different.
The easiest way to remember the distinction is:
Redis Pub/Sub = real-time communication Redis Streams = stored events with processing state
Choosing the wrong model can lead to lost events, unnecessary complexity, or unreliable processing. So let's explore how both work and when you should use each one.
Redis Pub/Sub is a lightweight messaging system based on the publish/subscribe pattern.
The architecture looks like this:
Publisher → Redis Channel → Subscribers
A publisher sends a message to a Redis channel.
Subscribers listening to that channel immediately receive the message.
For example, imagine an application publishing:
ORDER_CREATED
Several services might subscribe to that channel and react when the event arrives.
The important detail is that Redis Pub/Sub is essentially fire-and-forget messaging.
If a subscriber is connected when the message is published, it receives the message.
If the subscriber is offline, the message is lost for that subscriber.
There is no message history waiting for it when it reconnects.
How Redis Pub/Sub Works
Imagine an e-commerce platform with several application servers.
When product information changes, one server could publish a cache invalidation event:
PRODUCT_CACHE_INVALIDATED
Every active application server subscribed to the channel receives the event and clears its local cache.
The event only matters at that moment.
There is usually no reason for a server that starts several hours later to replay yesterday's cache invalidation messages.
This is exactly where Pub/Sub works well.
Typical Pub/Sub Flow
text
Application
|
| PUBLISH
v
Redis Channel
|
+--+--+------+
| | |
v v v
App A App B App C
Redis broadcasts the event to the subscribers currently listening to the channel.
Key Characteristics of Redis Pub/Sub
Redis Pub/Sub is designed for simplicity and speed.
It provides:
Real-time message delivery
One-to-many broadcasting
Lightweight communication
Simple publisher/subscriber architecture
Low messaging overhead
However, it does not provide several features required for reliable asynchronous processing.
Pub/Sub does not maintain a persistent event history for disconnected subscribers, and it does not provide consumer acknowledgments or consumer-group processing.
That makes it excellent for events that matter right now, but less appropriate for events that must eventually be processed.
When Should You Use Redis Pub/Sub?
Pub/Sub works best when missing an occasional message does not break your business workflow.
Common examples include:
Live Notifications
Applications can broadcast notifications to connected users in real time.
WebSocket Updates
Multiple backend instances can distribute events to WebSocket connections through Redis.
Cache Invalidation
Services can tell other application instances that cached information has changed.
Live Dashboards
Real-time metrics can be pushed to connected dashboards.
Presence and Typing Indicators
Applications such as chat systems often need extremely short-lived events.
For these scenarios, storing every message may add unnecessary complexity.
Think:
"This event matters now."
That is usually a strong signal that Redis Pub/Sub may be appropriate.
What Are Redis Streams?
Redis Streams solve a different problem.
Instead of simply broadcasting a temporary message, Redis Streams store events in an append-only log.
The architecture can look like:
Producer → Redis Stream → Consumer Group → Workers
A producer can append an event using XADD.
For example:
text
XADD orders * type ORDER_CREATED order_id 12345
Redis adds the event to the stream and assigns it an ID.
Unlike Pub/Sub, the event remains available after it is produced, subject to your retention and trimming strategy.
Consumers can then process those events later.
Why Stored Events Matter
Consider an e-commerce order.
A customer places an order and the system generates:
ORDER_CREATED
Several operations might depend on this event:
text
ORDER_CREATED
|
+----> Payment Service
|
+----> Inventory Service
|
+----> Shipping Service
|
+----> Analytics Service
Suppose the payment worker temporarily crashes.
With a fire-and-forget model, the event could be missed.
With Redis Streams, the event remains in the stream, allowing consumers to process or recover it later.
That difference is extremely important for business-critical workflows.
Redis Consumer Groups
One of the most powerful features of Redis Streams is consumer groups.
Consumer groups allow multiple workers to cooperate when processing events.
For example:
text
Redis Stream
|
Consumer Group
|
+----+----+----+
| | |
v v v
Worker A Worker B Worker C
Instead of every worker processing every message, Redis can distribute messages among workers within the group.
Workers typically read messages using:
text
XREADGROUP
After successfully processing a message, the worker acknowledges it using:
text
XACK
This gives applications much more control over message processing.
Pending Messages and Failure Recovery
Suppose Worker A receives an order event but crashes before finishing the operation.
Redis Streams can keep track of that event as pending.
Applications can inspect pending entries and recover work that has been left unfinished. Redis also provides mechanisms such as XCLAIM and XAUTOCLAIM for transferring stale pending work to healthy consumers.
This makes Streams useful for systems where losing an event is unacceptable.
Typical examples include:
Payment processing
Order processing
Inventory updates
Background jobs
Event-driven microservices
Data-processing pipelines
Think:
"I need to know what happened and what is still pending."
That is where Redis Streams become much more appropriate.
Redis Pub/Sub vs Redis Streams
The differences become clearer when we compare them directly.
Feature
Redis Pub/Sub
Redis Streams
Real-time delivery
Yes
Yes
Stores messages
No persistent subscriber history
Yes
Offline consumer recovery
No
Yes
Message replay
No
Yes
Consumer groups
No
Yes
Acknowledgments
No
Yes
Pending-message tracking
No
Yes
Failure recovery
Limited
Supported
Best for
Live communication
Reliable event processing
The key distinction isn't simply performance.
It is the messaging model.
Example: ORDER_CREATED
Let's compare the two approaches using the same event.
Using Pub/Sub
text
Order Service
|
| ORDER_CREATED
v
Redis Channel
|
+----+----+
| |
v v
Service A Service B
If Service B is offline when the message arrives, it does not receive that message later.
That could be perfectly acceptable if Service B only provides a live UI update.
But it could be disastrous if Service B processes payments.
Using Redis Streams
text
Order Service
|
| XADD
v
Redis Stream
|
Consumer Group
|
+----+----+
| |
v v
Worker A Worker B
The event becomes part of the stream.
Workers process messages and acknowledge successful processing.
If processing fails, the application's recovery strategy can detect pending work and retry or reassign it.
That makes Streams much better suited to important workflows.
Redis Streams Are Not Simply "Reliable Pub/Sub"
A common misconception is:
Redis Streams = Pub/Sub + persistence
That explanation is convenient but incomplete.
Streams represent a different messaging model.
Pub/Sub focuses primarily on broadcasting transient events.
Streams provide an ordered event log plus consumer-processing state.
That difference affects how applications handle:
Scaling
Retries
Backlogs
Consumer failures
Event replay
Delivery semantics
So the architecture should be chosen based on the workflow rather than simply choosing Streams because they offer more features.
What About Exactly-Once Processing?
Another important misconception is that Redis Streams automatically provide exactly-once business processing.
They do not magically eliminate duplicate side effects.
Consumer-group workflows commonly involve at-least-once delivery patterns, meaning an application should be prepared for an event to be processed again under certain failure conditions.
Consider this sequence:
text
1. Worker receives PAYMENT_REQUESTED
2. Worker charges customer
3. Worker crashes
4. XACK never happens
5. Event is recovered
6. Another worker processes it
Without additional safeguards, the customer could potentially be charged twice.
The solution is idempotent consumer design.
For example, before charging the customer, the payment service might check whether the transaction ID has already been processed.
Reliable messaging therefore requires both infrastructure support and good application design.
Can You Use Both?
Absolutely.
Many real-world architectures use Redis Pub/Sub and Redis Streams together because they solve different problems.
These events are temporary and mostly relevant to currently connected clients.
The resulting architecture might look like:
text
Application
|
+----------+----------+
| |
v v
Redis Streams Redis Pub/Sub
| |
v v
Business Workflows Live Communication
| |
Orders / Payments WebSockets / Cache
Jobs / Microservices Notifications / UI
There is no requirement to choose only one.
When Redis Streams May Not Be Enough
Redis Streams can be an excellent solution, especially when Redis already exists in your infrastructure.
However, they should not automatically replace dedicated event-streaming or messaging platforms.
Very large event-driven systems may require capabilities offered by technologies such as Kafka, RabbitMQ, Pulsar, or NATS, depending on their requirements.
Factors to consider include:
Event volume
Required retention period
Routing complexity
Storage requirements
Durability requirements
Cross-region architecture
Operational complexity
Ecosystem integrations
Redis Streams can provide a particularly attractive middle ground when you need reliable event processing without introducing another major infrastructure platform.
A Simple Decision Framework
When deciding between Redis Pub/Sub and Redis Streams, ask one question:
What happens if the consumer is offline when the event occurs?
If your answer is:
"It doesn't matter."
Pub/Sub may be enough.
If your answer is:
"The consumer must process it when it comes back."
You probably need Streams or another durable messaging solution.
Another useful question is:
Do I need to know what has already been processed and what is still pending?
If yes, Redis Streams are the stronger choice.
Final Thoughts
Redis Pub/Sub and Redis Streams are both powerful tools, but they are designed for different messaging problems.
Use Redis Pub/Sub when you need lightweight, real-time broadcasting and messages only matter to consumers that are currently connected.
Use Redis Streams when events need to be stored, replayed, acknowledged, distributed across workers, or recovered after failures.
The simplest rule to remember is:
Pub/Sub = "Tell whoever is listening right now."
Streams = "Record what happened and make sure consumers can process it."
And for many production architectures, the best answer isn't Pub/Sub or Streams.
It's both—each used for the problem it was designed to solve.