Resumable Streams
Recover in-progress AI responses after a dropped connection, sync the same chat across tabs and devices, and keep streams alive across scaled-out instances.
Resumable streams let an in-progress AI response survive a dropped connection. If the network drops, the browser refreshes, or you switch tabs or devices, LibreChat reconstructs the content that was already streamed and continues from where it left off. The same mechanism keeps multiple viewers of one conversation in sync.
What You Get
- No lost responses. Network drops, browser refreshes, and server restarts do not discard streamed content.
- Tabs stay in sync. Open one conversation in two browser tabs and both receive the same updates in real time.
- Switch devices mid-stream. Start a generation on your desktop and pick up the result on your phone.
- Background generations. Start a long response, move to another tab or app, and the full response is there when you return.
- Shared conversations. Every viewer of a shared chat sees content stream in at the same time.
How It Works
When you send a message, LibreChat creates a generation job that records every streamed delta. If the connection breaks:
- The client detects the disconnection.
- On reconnect, the server rebuilds the content streamed so far from the job's recorded deltas.
- The missing content is delivered in a single sync event.
- Streaming continues from the current position.
This runs automatically and requires no user action.
Deployment Modes
LibreChat ships with two backends for resumable streams.
Single-Instance Mode (default)
Stores stream state in memory and uses a Node.js EventEmitter for pub/sub. This is the default and needs no configuration. It covers local development, single-server deployments, and Docker Compose setups.
Redis Mode (production)
Uses Redis Streams and Pub/Sub so stream state is shared across instances. Use it for horizontally scaled, load-balanced, or high-availability deployments, including Kubernetes clusters. With Redis, a generation started on one instance can resume on another, which keeps active streams alive through rolling deployments and auto-scaling.
Single instance? You likely don't need Redis here
In-memory mode handles everything for a single LibreChat instance. Redis becomes relevant once you run multiple instances behind a load balancer. Redis is still useful for caching and session storage in single-instance deployments, just not specifically for resumable streams.
Configuration
Enable Redis Streams
Setting USE_REDIS=true makes resumable streams use Redis automatically. Use USE_REDIS_STREAMS to control it explicitly.
USE_REDIS=true
REDIS_URI=redis://localhost:6379
# Resumable streams use Redis automatically when USE_REDIS=true.
# Set USE_REDIS_STREAMS to control it explicitly:
USE_REDIS_STREAMS=trueRedis Cluster
For a Redis Cluster, enable cluster mode and list the nodes in REDIS_URI.
USE_REDIS_STREAMS=true
USE_REDIS_CLUSTER=true
REDIS_URI=redis://node1:7001,redis://node2:7002,redis://node3:7003LibreChat uses hash-tagged keys so that multi-key operations land on the same cluster slot.
What Gets Reconstructed
On reconnect, LibreChat aggregates the recorded delta events to rebuild:
- Message content (text, tool calls, citations)
- Agent run steps and intermediate reasoning
- Metadata and state information
The storage mechanism depends on the deployment mode:
| Component | Storage Mechanism |
|---|---|
| Chunks | Redis Streams (XADD/XRANGE) |
| Job metadata | Redis Hash structures |
| Real-time events | Redis Pub/Sub channels |
| Expiration | Automatic TTL after stream completion |
LibreChat applies a few optimizations to keep this cheap:
- Memory-first recovery. Reconnecting to the same instance reads from local cache, avoiding a Redis round trip.
- Cleanup on access. Stale job entries are removed during queries, and completed streams expire automatically.
- Garbage-collected storage. In-memory mode stores stream graphs with
WeakRef, so they are collected once a conversation ends.
Testing
To confirm the feature is working, start a streaming conversation with any model, then try one of:
- Tabs. Open the same chat in a second tab; both should sync.
- Disconnect. Drop the network briefly, then reconnect.
- Navigation. Navigate away mid-stream, then return.
Each case should produce the complete response with no missing content.
Troubleshooting
Streams not resuming. Confirm Redis is reachable and that USE_REDIS_STREAMS is set.
docker exec -it librechat-redis redis-cli ping
# Expected: PONG
echo $USE_REDIS_STREAMSContent appears duplicated. This usually means a client version mismatch. Update to the latest version of LibreChat.
High memory use in single-instance mode. Completed streams are garbage collected. If memory stays high, look for very long-running streams that never complete or streams that errored without cleaning up.
Related Documentation
- Redis Configuration: setting up Redis for caching and horizontal scaling
- Agents: AI agents with tool use
- Docker Deployment: container-based deployment
For implementation details, see PR #10926.
How is this guide?