Real-time Scaling Challenges
Part of the Backend Developer Roadmap
In short
Real-time works beautifully on one server. Add a second server behind a load balancer and suddenly half your users stop getting messages. Here's why, and the fix.
The specific difficulties of scaling WebSocket connections horizontally — since a client stays connected to one specific server instance, broadcasting to all clients requires coordination across instances.

Think of it like this
Waiters at a big wedding
One waiter can serve the tables he's standing near. Hire a second waiter for the other hall, and a guest in hall A asking to 'send sweets to my cousin' fails, because the cousin is in hall B. Waiters need a shared walkie channel to pass messages between halls.
Watch it happen
Riya and Aman on different servers
chat "hello"
1/5The load balancer put Riya's socket on Server 1. She sends a message to the room.
The big ideas
What you need to know
Share messages between servers
Each server only holds its own sockets. A pub/sub backbone like Redis passes events between all of them.
Sticky sessions
Long polling sends many requests per client. They must hit the same server, so turn on sticky sessions at the load balancer.
Connections cost memory
Each open socket holds memory and a file descriptor. Plan capacity by concurrent connections, not requests per second.
Reconnect storms
Deploy a new version and every client reconnects at once. Add random jitter to client retries so they spread out.
See it in code
Walk through the code
1import { Server } from "socket.io";2import { createClient } from "redis";3import { createAdapter } from "@socket.io/redis-adapter";4 5const pubClient = createClient({ url: process.env.REDIS_URL });6const subClient = pubClient.duplicate();7await Promise.all([pubClient.connect(), subClient.connect()]);8 9const io = new Server(3000, { adapter: createAdapter(pubClient, subClient) });10// io.to("room-7").emit(...) now reaches sockets on every server1/2Two Redis connections: one to publish broadcasts, one to listen for broadcasts from other servers.
Your emit code doesn't change at all. The adapter quietly forwards every room broadcast through Redis to the other instances.
Save yourself the pain
Common mistakes
Oops
Testing real-time features only with one local server.
Do this instead
Run two instances on different ports behind a simple proxy before launch, and test cross-server messages.
Oops
Keeping online-user lists in a JavaScript Map on each server.
Do this instead
Store presence in Redis with expiry, so every server sees the same list.
Your mission
Break it with two servers, then fix it
Quick check
Why does a chat message fail to reach a user on another server without an adapter?
Go deeper
- 1Diagram the problem: a message needs to reach clients connected to different server instances.
- 2Learn how a Redis pub/sub adapter solves this for Socket.io across multiple instances.
- 3Understand sticky sessions and why load balancers need special config for WebSocket traffic.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.