1.Connection affinity and connection registries
A WebSocket is a long-lived, stateful TCP connection — once a client's handshake completes, that specific connection is held open in the memory of exactly one server process, on exactly one machine. This is connection affinity: unlike a stateless HTTP request, which any server behind a load balancer can answer, a WebSocket message can only be pushed to a client through the one process that is holding its open socket. A connection registry is the piece of shared infrastructure — usually Redis or a database — that records which server instance currently holds which user's connection, so any other part of the system can look up where to send a message.
Key features
- A WebSocket connection is pinned to the single server process that accepted its handshake — it is not interchangeable the way a stateless HTTP request is
- Connection affinity is usually enforced at the load balancer with sticky sessions (routing reconnects back to the same backend) or at the protocol level via a connection ID
- A connection registry maps identity (user ID, connection ID) to location (which server instance, which process) and must be shared and fast — typically Redis hashes or sets, keyed by user ID
- The registry must be updated on connect, on disconnect, and on any server crash — a stale entry pointing at a dead instance causes messages to silently go nowhere
- Without a registry, one instance has no way to know that a given user is even connected, let alone which of N instances holds that connection
Stateless HTTP vs stateful WebSocket routing
- Client → server-7: WebSocket handshake
- server-7 → Registry: user:482 → server-7
- server-3 → Registry: lookup user:482
- Registry → server-3: server-7
- server-3 → server-7: relay via pub/sub
- server-7 → Client: write to live socket
Command
// Connection registry as a Redis hash, updated on connect/disconnect
HSET conn:registry user:482 instance:server-7
EXPIRE conn:registry:user:482 90 -- guards against stale entries
// On disconnect (graceful or crash-detected via heartbeat)
DEL conn:registry:user:482A WebSocket is pinned to one server process (connection affinity) — a registry (typically Redis, with a short TTL refreshed by heartbeats) is the only way other instances learn where a given user's connection actually lives.