# Redis Stream

{% hint style="info" %}
SocketIO4J uses the Redisson client to connect to a Redis server. Alternative Redis-compatible backends such as Valkey and DragonflyDB may also be supported.
{% endhint %}

The **RedisStreamEventStore** provides a distributed, streaming event store for socketio4j using **Redis Streams (XADD / XREAD)**.\
It enables horizontal scaling by synchronizing events across multiple server instances so that internal state, room membership, and other distributed operations remain consistent across nodes.

> Redis Reliable Pub/Sub uses Streams internally for durability, but does not expose offsets; Redis Streams exposes offsets directly, enabling controlled replay and connection-state recovery feature(planned for development).

**Key characteristics**

* **Distributed streaming** — uses Redis Streams to deliver events to all active nodes
* **Event replay continuity** — stores recent events in stream history, allowing controlled replay
* **Offset tracking per-event-type** — each event type maintains its own last-seen `StreamMessageId`
* **Streaming dispatch** — events processed asynchronously without blocking Netty event loops
* **Duplicate prevention** — events produced by the same node are filtered with `nodeId`

**How it works**

* Every publish performs `XADD` to a Redis stream (single or per-type depending on mode)
* Each event type maintains its own read offset using `StreamMessageId`
* Polling is performed in dedicated scheduled executor threads per event type
* For each read (`XREAD`), only messages with offsets newer than the last processed id are handled
* Events are delivered to listeners only if they **came from another node**
* On errors or stream timeouts, retries are scheduled automatically

**Modes**

| Mode             | Behavior                                 | When to use                                                      |
| ---------------- | ---------------------------------------- | ---------------------------------------------------------------- |
| `MULTI_CHANNEL`  | Separate Redis stream per event type     | Default; isolates event traffic and reduces contention           |
| `SINGLE_CHANNEL` | All events fed into `ALL_SINGLE_CHANNEL` | When global ordering of all event types is required across nodes |

**Advantages**

👍 Works well for multi-node deployments\
👍 Messages can survive temporary subscriber downtime depending on stream length\
👍 Provides **offset-based delivery**\
👍 Supports controlled replay of new events after restarts (connection state recovery feature is in development, for now you will the get the message offset)\
👍 Uses core Redis Streams primitives without external brokers

**Limitations**

ℹ️ Consumers process messages independently — ordering is per-stream, not global\
ℹ️ Potential duplicate delivery on restarts or offset boundary races\
ℹ️ Requires Redis Streams support (not compatible with legacy Redis Pub/Sub mode)

> **Delivery guarantee:** *At-least-once semantics — event listeners must be idempotent to handle possible duplicate messages.*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.socketio4j.org/adapters/event-store/redis-stream.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
