Mastering Redis Streams: From Basics to SpringBoot Integration

This article introduces Redis Streams, explains its core concepts and commands, compares it with Kafka, demonstrates practical SpringBoot integration with code examples, and discusses its suitability as a lightweight message queue, highlighting advantages, limitations, and best‑practice considerations.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Mastering Redis Streams: From Basics to SpringBoot Integration

1. Basic Knowledge

Redis Streams, introduced in Redis 5.0, is a new data structure for message passing. It is a linked list of messages where each message has a unique ID and payload.

Each stream has a unique name that corresponds to a Redis key. A stream can have multiple consumer groups (ConsumerGroup), which must be created with the XGROUP CREATE command.

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

Consumer groups can have multiple consumers; each consumer reads messages in parallel, also advancing the group cursor.

Consumers keep a pending_ids list of messages they have read but not yet acknowledged.

The design of Redis Streams resembles Kafka (consumer groups, offset tracking), but the internal implementation differs: Kafka relies on the file system and partitions, while Redis Streams store data in memory.

2. Core Commands

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

Syntax: XADD key ID field value [field value ...] key : stream name (created if it does not exist)

ID : message ID; use * for an auto‑generated ID or provide a custom increasing ID

field value : the message payload

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

The auto‑generated ID consists of a millisecond timestamp and a sequence number (e.g., 1712473185388-5).

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

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

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"

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

Syntax:

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

count : maximum number of entries to return

milliseconds : optional block time; omitted means non‑blocking

key : stream name(s)

id : last ID you have seen (use 0-0 to read from the beginning, $ for the latest)

XREAD streams mystream 0-0
1) "mystream"
   1) "1712473185388-0"
      1) "name1"
      2) "value1"
      3) "name2"
      4) "value2"
   2) "1712473231761-0"
      1) "name2"
      2) "value2"
      3) "name3"
      4) "value3"

Using BLOCK with $ makes the call wait until new messages arrive.

04 XGROUP CREATE – Create a Consumer Group

Two ways to create a group:

XGROUP CREATE mystream mygroup 0-0   # start from the beginning
XGROUP CREATE mystream mygroup $     # start from the latest message

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 within the group

count : number of entries to return

milliseconds : optional block time

key : stream name

ID : start ID (use > to read new messages)

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

06 XACK – Acknowledge Processed Messages

Syntax:

XACK key group ID [ID ...]
XACK mystream mygroup 1713089061658-0
(integer) 1

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

07 XTRIM – Trim a Stream’s Length

Example of adding messages and then trimming to keep only the latest two entries:

XADD mystream * field1 A field2 B field3 C field4 D
"1712535017402-0"
XTRIM mystream MAXLEN 2
(integer) 4
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"

Redis Streams support both simple producer‑consumer and publish‑subscribe models.

3. SpringBoot Redis Stream Practical Guide

Add the SpringBoot Redis starter dependency:

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

Configure connection properties in application.yml (example omitted for brevity).

Configure a RedisTemplate bean to work with streams.

Define a stream listener class that implements MessageListener (code omitted).

Create a StreamContainer bean to start the listener.

Send messages using RedisTemplate.opsForStream().add(...).

When the application runs, the consumer prints received messages as shown in the logs.

Note: Ensure that the stream key and consumer group are created before starting the listener.

4. Is Redis Stream Perfect for a Message Queue?

Redis Streams bring a publish‑subscribe model with independent consumption and one‑to‑many delivery, solving the lack of ACK in Redis Lists.

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

Therefore, Redis Streams are best suited for lightweight queue scenarios where data volume is controlled, the business model is simple, message buildup is unlikely, and proper monitoring is in place.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

SpringBootStreamsKafka Comparison
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

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.