Databases 14 min read

Understanding Redis Streams: Core Commands and SpringBoot Integration

The article introduces Redis Streams as a Kafka‑like messaging structure, explains its fundamental concepts and seven core commands (XADD, XRANGE, XREAD, XGROUP CREATE, XREADGROUP, XACK, XTRIM), demonstrates integration with Spring Boot, and evaluates its fit for lightweight, low‑backlog queue scenarios.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Understanding Redis Streams: Core Commands and SpringBoot Integration

Redis Stream is a new data structure introduced in Redis 5.0 for implementing messaging functionality.

This article shares the author’s experience learning Redis Stream and aims to inspire readers.

1 Basic Knowledge

Redis Stream is a linked list of messages, each with a unique ID and associated content.

Each Stream has a unique name that corresponds to a Redis key.

A single Stream can have multiple consumer groups (ConsumerGroup). Consumer groups must be created explicitly with the XGROUP CREATE command.

Each consumer group maintains a cursor last_delivered_id that moves forward whenever any consumer reads a message, indicating the group’s consumption progress.

Consumer groups can have multiple consumers. Each consumer reads messages in parallel, and any read operation also advances the group cursor.

Consumers have a pending_ids list that records IDs of messages that have been read but not yet acknowledged (ACK).

The design of Redis Stream is similar to Kafka, featuring consumer groups and offset tracking, but the internal implementation differs.

2 Core Commands

01 XADD – Add a Message to the End of a Stream

Syntax:

XADD key ID field value [field value ...]

key : name of the stream; created if it does not exist.

ID : message ID; * lets Redis generate an ID, otherwise a custom ID must be monotonically increasing.

field value : the data fields of the message.

127.0.0.1:6379> XADD mystream * name1 value1 name2 value2
"1712473185388-0"
127.0.0.1:6379> XLEN mystream
(integer) 1
127.0.0.1:6379> XADD mystream * name2 value2 name3 value3
"1712473231761-0"

The message ID format is timestamp-sequence , e.g., 1712473185388-5 .

You can also limit the stream length when adding a message:

127.0.0.1:6379> XADD mystream MAXLEN 100 * name value1 age 30
"1713082205042-0"

02 XRANGE – Retrieve a List of Messages

Syntax:

XRANGE key start end [COUNT count]

key : stream name.

start : start ID (use - for the minimum).

end : end ID (use + for the maximum).

count : optional limit on the number of entries returned.

127.0.0.1:6379> XRANGE mystream - + COUNT 2
1) "1712473185388-0"
   1) "name1"
   2) "value1"
   3) "name2"
   4) "value2"
2) "1712473231761-0"
   1) "name2"
   2) "value2"
   3) "name3"
   4) "value3"

The result shows message IDs followed by their hash‑style field/value pairs.

03 XREAD – Read Messages (Blocking or Non‑Blocking)

Syntax:

XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]

count : number of entries to return.

milliseconds : optional block time; omitted means non‑blocking.

key : stream name.

id : last ID that was processed.

127.0.0.1:6379> XREAD streams mystream 0-0
1) "mystream"
   1) "1712473185388-0"
   2) "name1"
   3) "value1"
   4) "name2"
   5) "value2"
2) "1712473231761-0"
   ...

Using the BLOCK option makes the command wait for new messages if none are available:

127.0.0.1:6379> XREAD block 1000 streams mystream $
(nil)
(1.07s)

04 XGROUP CREATE – Create a Consumer Group

Two ways to create a group:

From the beginning of the stream:

XGROUP CREATE mystream consumer-group-name 0-0

From the end of the stream (new messages only):

XGROUP CREATE mystream consumer-group-name $

Example:

127.0.0.1:6379> XGROUP CREATE mystream mygroup 0-0
OK

05 XREADGROUP – Read Messages from a Consumer Group

Syntax:

XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]

group : consumer group name.

consumer : consumer name.

count : max number of messages to read.

milliseconds : optional block time.

key : stream name.

ID : start ID (use > for “new messages”).

127.0.0.1:6379> XREADGROUP GROUP mygroup consumerA COUNT 1 STREAMS mystream >
1) "mystream"
   1) "1712473185388-0"
   2) "name1"
   3) "value1"
   4) "name2"
   5) "value2"

06 XACK – Acknowledge Processed Messages

Syntax:

XACK key group-key ID [ID ...]

Example:

127.0.0.1:6379> XACK mystream mygroup 1713089061658-0
(integer) 1

Acknowledgement removes the message from the pending list, increasing reliability.

07 XTRIM – Trim a Stream’s Length

Syntax:

XTRIM key MAXLEN count

Example:

127.0.0.1:6379> XADD mystream * field1 A field2 B field3 C field4 D
"1712535017402-0"
127.0.0.1:6379> XTRIM mystream MAXLEN 2
(integer) 4
127.0.0.1:6379> XRANGE mystream - +
1) "1712498239430-0"
   1) "name"
   2) "zhangyogn"
2) "1712535017402-0"
   1) "field1"
   2) "A"
   3) "field2"
   4) "B"
   5) "field3"
   6) "C"
   7) "field4"
   8) "D"

Through these seven core commands, Redis Stream supports both simple producer‑consumer models and publish‑subscribe patterns.

3 SpringBoot Redis Stream Practice

Code repository: https://github.com/makemyownlife/courage-cache-demo

1. Add SpringBoot Redis dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2. Configure application.yml (configuration screenshot omitted).

3. Configure RedisTemplate (configuration screenshot omitted).

4. Define a Stream listener (screenshot omitted).

5. Define StreamContainer and start it (screenshot omitted).

6. Send a message (screenshot omitted).

After execution, the consumer prints logs confirming successful consumption (screenshot omitted).

Key points for SpringBoot integration:

Ensure the stream key and consumer group are created before registering.

4 Is Redis Stream Perfect for a Message Queue?

Redis Stream brings a publish‑subscribe model, offering independent consumption and one‑to‑many communication.

However, Redis is fundamentally an in‑memory database designed for caching, not for heavy message accumulation. Its high‑availability mechanisms (AOF, asynchronous replication) may lose messages, whereas dedicated message queues provide stronger guarantees.

Therefore, Redis Stream is suitable for lightweight message‑queue scenarios where:

Data volume is controllable.

Business model is simple.

Message backlog probability is low.

Monitoring and alerting are in place.

Open‑source projects referenced:

SMS service: https://github.com/makemyownlife/platform-sms

Sharding practice: https://github.com/makemyownlife/shardingsphere-jdbc-demo

If this article helped you, please like, view, or share it to encourage further high‑quality content.

RedisMessage QueueSpringBootStreamConsumer GroupRedis Commands
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.