Index/WebSockets

SponsorGitHub
Key technologyPush transport4 min

WebSockets

Persistent connections for server push — and the stateful tier, routing and reconnect story they drag in.

At a glance

What it is
An HTTP Upgrade into a persistent, full-duplex TCP connection
Overhead
A few bytes of framing per message, not a full request
The tier
Stateful: it scales on open connections and memory, not CPU
Routing
A registry in Redis, or pub/sub per channel
Liveness
Ping frames — TCP will not tell you a phone entered a tunnel
Guarantee
None. Persist first, push second, resume from a cursor

Key concepts and capabilities

The short listwhat it gives you
Pick the cheapest transport — polling, long polling, SSE, then WebSockets; if the client only receives, SSE wins
The tier is stateful — it scales on open connections and memory per connection, not on CPU
Routing is the real problem — the message arrives at one node, the socket lives on another
Two answers: a user → node registry in Redis, or pub/sub where each node subscribes for its own connections
Heartbeats — ping frames and a timeout, because a phone in a tunnel does not close its TCP connection
Persist first, push second — the socket is a transport, never the delivery guarantee
Reconnect and backfill — the client resumes from its last message id and the server serves the gap
Deploys drain, they do not cut — otherwise every client reconnects at once, against you
Fan-out costs sends — a 100k-member room is 100k pushes; batch per node, or reconsider a pull-based feed

Use cases

Delivering a chat message to the right node

The whole design in one picture: the sender's socket is on node 1, the recipient's on node 7, and the message has to cross. Persist before publishing, so a dropped push costs a reconnect rather than a message.

DatabaseQueue / streamFocusClick a node for details

Coming back after the tunnel

Connections drop constantly, so the interesting path is the reconnect: the client sends the highest message id it holds, the server returns everything after it from durable storage, and only then does the live stream resume.

DatabaseFocusClick a node for details

Presence, without lying about it

Presence is heartbeats plus a TTL: each node refreshes a key while the socket is alive, and the key expiring is the disconnect event. Without it, TCP will happily hold a connection to a phone that left the network minutes ago.

Fanning out to a big room

One message to a 100k-member channel is 100k sends. Batch per node so the publish crosses the network once per node rather than once per member — and at some size, admit that a pull-based feed is the right answer instead.

Queue / streamFocusClick a node for details