Redis Streams: Complete Guide to Real-Time Data
Redis Streams is one of the most underrated features in Redis. Introduced in Redis 5.0 (2018), it provides a log-like data structure that's perfect for event sourcing, message queues, activity feeds, and real-time data processing. If you've been using Redis Lists or Pub/Sub for messaging, Streams might be what you actually need.
What Are Redis Streams?
A Stream is an append-only log. You add entries to the end, and they stay in order forever (or until you trim them). Each entry has a unique ID and contains field-value pairs, basically key-value data with guaranteed ordering.
The * tells Redis to auto-generate the ID (timestamp-sequence format). The entry contains three fields: user, action, and ip.
Unlike Pub/Sub, Stream entries persist. Unlike Lists, Streams support consumer groups for distributed processing. It's the best of both worlds.
Why Streams Over Pub/Sub?
Redis Pub/Sub has a fundamental limitation: if a subscriber isn't connected when a message is published, the message is lost. There's no history, no replay, no persistence.
Streams solve this:
A consumer that crashes and restarts can pick up where it left off. New consumers can replay the entire history. This changes what's possible.
Basic Stream Operations
Adding Entries
Reading Entries
Blocking Reads
The $ means "only new entries." You can also specify an ID to read entries after that point.
Consumer Groups
Consumer groups enable distributed processing. Multiple consumers share the workload, and Redis tracks what each consumer has processed.
Creating a Consumer Group
Reading with Consumer Groups
Multiple workers can call XREADGROUP simultaneously. Redis distributes entries across them automatically.
Acknowledging Entries
After processing, acknowledge the entry:
Unacknowledged entries can be claimed by other consumers if the original consumer crashes (using XPENDING and XCLAIM).
Handling Failed Consumers
Real-World Use Cases
Event Sourcing
Store every state change as an event:
Activity Feeds
Work Queue with Retries
Stream Management
Trimming
Streams grow forever by default. Trim them:
Getting Stream Info
Performance Considerations
Streams are efficient, but keep these in mind:
Memory: Each entry stores field names. If you have millions of entries with the same fields, consider shorter field names or use JSON in a single field.
Consumer Groups: Add overhead for tracking delivery. If you don't need exactly-once processing semantics, simple XREAD is faster.
Trimming: Use MAXLEN ~ (approximate) rather than exact for better performance. The ~ allows Redis to trim in larger batches.
Blocking Reads: Use reasonable timeouts. Very long blocks can cause connection issues with some clients.
When to Use Redis Streams
Good fits:
- Event sourcing and audit logs
- Activity feeds and timelines
- Work queues with retry support
- Real-time analytics pipelines
- Chat message history
- IoT sensor data
Consider alternatives:
- If you need complex routing: RabbitMQ or Kafka
- If you need guaranteed persistence: Kafka or a database
- If you need pub/sub without history: Redis Pub/Sub
- If you need massive scale (millions of messages/second): Kafka
Summary
Redis Streams fills a gap between simple message queues and full event streaming platforms. It's powerful enough for serious use cases but simple enough to understand in an afternoon.
Key takeaways:
- Streams are append-only logs with persistent storage
- Consumer groups enable distributed, fault-tolerant processing
- Use
MAXLEN ~to control memory usage - The
XPENDING/XCLAIMpattern handles failed consumers - Perfect for event sourcing, activity feeds, and work queues
If you're currently using Redis Lists for queuing or Pub/Sub for events, Streams is worth evaluating. The persistence and consumer group features solve real problems.