Skip to content

Redis Streams

A Redis Stream is a data structure that behaves like a persistent, ordered log. Unlike Pub/Sub — where messages vanish the moment they are delivered — a stream stores every entry and lets you read them again at any time, from any position.

Each entry has two parts:

  • ID — a unique timestamp-based identifier in the form <milliseconds>-<sequence>. You can let Redis generate it automatically by passing *, or supply your own.
  • Fields — one or more key-value pairs that form the payload of the entry, similar to a hash.

Streams are ideal for event logs, activity feeds, metrics pipelines, and any workload where you need both real-time delivery and historical replay.

XADD key id field value [field value ...] appends a new entry to the stream. Using * as the ID lets Redis assign a monotonically increasing timestamp-based ID automatically.

127.0.0.1:6379> XADD events * action "login" user "ada"
"1526919030474-0"
127.0.0.1:6379> XADD events * action "purchase" user "ada" item "book"
"1526919030474-1"
127.0.0.1:6379> XLEN events
(integer) 2

XLEN returns the number of entries currently in the stream — exactly like LLEN for lists.

XRANGE key start end [COUNT n] returns entries from oldest to newest. Two special IDs simplify range queries:

  • - — the earliest entry in the stream
  • + — the latest entry in the stream

XREVRANGE key end start reverses the direction, returning entries newest-first.

127.0.0.1:6379> XRANGE events - +
1) 1) "1526919030474-0"
2) 1) "action"
2) "login"
3) "user"
4) "ada"
2) 1) "1526919030474-1"
2) 1) "action"
2) "purchase"
3) "user"
4) "ada"
5) "item"
6) "book"
127.0.0.1:6379> XRANGE events - + COUNT 1
1) 1) "1526919030474-0"
2) 1) "action"
2) "login"
3) "user"
4) "ada"
127.0.0.1:6379> XREVRANGE events + - COUNT 1
1) 1) "1526919030474-1"
2) 1) "action"
2) "purchase"
3) "user"
4) "ada"
5) "item"
6) "book"

XREAD COUNT n STREAMS key id reads up to n entries from the stream starting after the given ID. Passing 0 as the ID reads from the very beginning.

127.0.0.1:6379> XREAD COUNT 10 STREAMS events 0
1) 1) "events"
2) 1) 1) "1526919030474-0"
2) 1) "action"
2) "login"
3) "user"
4) "ada"
2) 1) "1526919030474-1"
2) 1) "action"
2) "purchase"
3) "user"
4) "ada"
5) "item"
6) "book"

To wait for entries that do not exist yet, add the BLOCK option with a timeout in milliseconds (0 means wait forever) and use $ as the ID — $ means “only entries newer than the last one at the time this command was issued”:

127.0.0.1:6379> XREAD BLOCK 0 STREAMS events $
(Blocks until a new entry arrives...)

This turns XREAD into a long-poll listener. When another client runs XADD events * ..., the blocked client receives the new entry immediately.

XADD events * action "login" user "ada"
XADD events * action "purchase" user "ada" item "book"
XLEN events
XRANGE events - +
XREAD COUNT 10 STREAMS events 0
What does passing `*` as the ID to XADD do?
Which XRANGE argument means 'the earliest entry in the stream'?
What does the sequence number in an entry ID like `1526919030474-3` represent?
What is the key difference between Redis Streams and Redis Pub/Sub?