Why You Need It
As established with the default in-memory adapter, a single Node.js process cannot deliver room broadcasts to sockets connected to a different process, which becomes a hard requirement to solve the moment you run more than one Socket.IO server instance behind a load balancer for availability or throughput. The @socket.io/redis-adapter package solves this by having every server instance both publish outgoing broadcast events to a shared Redis pub/sub channel and subscribe to that same channel, so when instance A calls io.to(room).emit(), the event is published to Redis, and every other instance (including A itself) receives it and delivers it to any locally-connected sockets that are members of that room.
Cricket analogy: It's like a national broadcaster's central feed that every regional commentary booth subscribes to and also pushes updates into — a wicket called at the Chennai booth is instantly relayed through the central feed to the Mumbai booth's live commentary, rather than each city working in isolation.
// npm install @socket.io/redis-adapter redis
import { createClient } from 'redis';
import { createAdapter } from '@socket.io/redis-adapter';
import { Server } from 'socket.io';
const pubClient = createClient({ url: 'redis://redis-cluster:6379' });
const subClient = pubClient.duplicate();
await Promise.all([pubClient.connect(), subClient.connect()]);
const io = new Server(httpServer, {
adapter: createAdapter(pubClient, subClient),
});
// Application code is unchanged — broadcasts now work across all instances
io.on('connection', (socket) => {
socket.on('join-room', (room) => socket.join(room));
});
io.to('room-42').emit('update', { status: 'live' });Two Separate Redis Clients
The adapter requires two distinct Redis client connections — a pubClient for publishing and a subClient for subscribing — because a single Redis connection that has issued a SUBSCRIBE command enters a special mode where it can no longer execute regular commands like PUBLISH; this is a fundamental constraint of the Redis protocol, not a Socket.IO design choice. The idiomatic pattern is to create one client and .duplicate() it for the second role, which reuses the same connection configuration (host, auth, TLS) without re-specifying it.
Cricket analogy: It's like a stadium PA needing a separate microphone line from its speaker line — you can't broadcast an announcement and simultaneously listen for the umpire's radio call over the exact same physical wire.
Sticky Sessions Are Still Required
The Redis adapter solves cross-instance broadcasting, but it does not eliminate the need for sticky sessions (also called session affinity) at the load balancer level when using HTTP long-polling, because a single logical Socket.IO connection may issue multiple sequential HTTP requests that must all land on the same server process to maintain connection state. With WebSocket-only transport this concern mostly disappears since the connection is a single persistent TCP connection, but most production setups still configure sticky sessions (e.g., via ip_hash in nginx or cookie-based affinity in AWS ALB) as a safety net for polling fallback and for the initial HTTP handshake.
Cricket analogy: It's like requiring the same match referee to officiate every session of a Test match rather than swapping referees mid-day — even with perfect communication between referees (Redis), continuity of who's actually watching the pitch still matters for consistent decisions.
Forgetting sticky sessions is one of the most common production bugs when adding the Redis adapter: teams add Redis, assume scaling is 'solved', but still see intermittent connection failures because the load balancer round-robins polling requests across instances that don't share in-flight HTTP session state.
Beyond Redis, Socket.IO also supports adapters backed by MongoDB, Postgres, and a cluster-adapter for Node.js's built-in cluster module — the choice usually comes down to what infrastructure you already operate and its latency characteristics, since Redis pub/sub is typically the lowest-latency option.
- The Redis adapter enables room broadcasts to reach sockets connected to any server instance in a multi-process cluster.
- It works by having every instance publish and subscribe to shared Redis pub/sub channels.
- Two separate Redis clients are required (pub and sub) because a subscribed connection can't issue other commands.
- The idiomatic setup uses client.duplicate() to create the second connection with identical config.
- Application-level room/broadcast code (io.to(room).emit()) requires no changes when adding the Redis adapter.
- Sticky sessions at the load balancer are still needed, especially for HTTP long-polling fallback and the initial handshake.
- Alternatives exist (MongoDB adapter, Postgres adapter, cluster adapter) depending on existing infrastructure.
Practice what you learned
1. What mechanism does the Redis adapter use to synchronize events across server instances?
2. Why does the Redis adapter require two separate Redis client connections?
3. Does adding the Redis adapter eliminate the need for sticky sessions at the load balancer?
4. What is the idiomatic way to create the second Redis client needed by the adapter?
5. What does application code that calls io.to(room).emit() need to change when adopting the Redis adapter?
Was this page helpful?
You May Also Like
The Socket.IO Adapter
Learn what the Socket.IO adapter is, how it powers rooms and broadcasting under the hood, and why the default in-memory adapter breaks down once you run more than one server process.
Handling Reconnection
Understand Socket.IO's built-in automatic reconnection behavior, how to configure and tune it, and how to restore application state like room membership after a client reconnects.
Joining and Leaving Rooms
Learn how Socket.IO rooms let you group sockets together so you can broadcast to a subset of connected clients, and how sockets join, leave, and get cleaned up automatically on disconnect.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics