Cross-server Socket.IO communication in horizontal scaling?
distributed system messaging and adapter patterns.
local io.emit() only reaches local sockets, need adapter (Redis) for inter-server broadcast.
assuming io.emit() broadcasts globally without an adapter; it doesn't.
LOCAL ISOLATION PROBLEM
Each Node.js instance runs Socket.IO independently with its own in-memory socket registry. When server A calls io.emit('event', data), only sockets connected to server A receive it. If a client is connected to server B, they never see the event. This is the default behavior and causes silent failures in scaled systems.
WHY ADAPTERS EXIST
Socket.IO adapters abstract the socket registry to a shared system. The default adapter stores sockets in memory, scoped to one server. For clusters, you use a different adapter (Redis adapter is standard) that stores room and socket information in a shared database. Now io.emit() automatically broadcasts through Redis to all servers.
REDIS ADAPTER FLOW
Setup: npm install socket.io-redis, then initialize: io.adapter(require('socket.io-redis')({ host: 'localhost', port: 6379 }));. When server A emits, it writes the message to Redis. Server B's Socket.IO listens to Redis, receives the message, and delivers it to its local sockets. This is transparent: application code doesn't change.
ROOM BROADCASTING ACROSS SERVERS
When both server A and B have sockets in 'room:123', io.to('room:123').emit() reaches all sockets in that room across both servers. Without the adapter, each server reaches only its local room members, causing some users to miss the message.
LIMITATIONS AND TRADE-OFFS
Redis adds a network hop, introducing slight latency (usually 1-5ms). For very high message rates, Redis can become a bottleneck. However, correctness is more important than a few milliseconds. For extreme scale, you might partition rooms across servers manually, but that sacrifices simplicity and is rarely needed.
TESTING WITHOUT ADAPTER
Instead of manually testing across servers, you can simulate the adapter behavior locally: run multiple Node.js instances on different ports, configure each with the same Redis, then verify messages cross instances. Docker Compose is useful here.
Read the original → socket.io
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.