WebSockets
A persistent, two-way channel between browser and server. Brilliant when both sides talk often; the price is stateful connections you now have to scale, heartbeat and reconnect.
On this page
A WebSocket is a full-duplex channel over a single TCP connection. Once it’s open, either side can send a message at any time — no request needed. That’s what makes chat, multiplayer games, collaborative editors and trading screens feel live.
How it starts
A WebSocket begins life as an ordinary HTTP request with an Upgrade: websocket header. If the server agrees, it replies
101 Switching Protocols, and from then on the connection carries framed messages in both directions instead of
request/response pairs.
const ws = new WebSocket("wss://example.com/prices");
ws.onopen = () => ws.send(JSON.stringify({ subscribe: ["BTC-USD"] }));
ws.onmessage = (e) => handle(JSON.parse(e.data));
When to use it (and when not)
| Need | Reach for |
|---|---|
| Both sides send frequently (chat, collaboration, games, order entry) | WebSockets |
| Only the server pushes (feeds, notifications, progress, LLM token streams) | Server-Sent Events (SSEs) — simpler, plain HTTP |
| Updates are rare or freshness isn’t critical | AJAX Polling |
| Long-lived connections are blocked | HTTP Long Polling |
The costs nobody mentions in the tutorial
- Stateful connections. Each server holds its own sockets, so a message for a user has to reach whichever server they’re connected to. The usual fix is a pub/sub backplane (Redis, NATS, Kafka) plus a registry of who’s connected where.
- Load balancers need WebSocket support and generous idle timeouts.
- Dead peers look alive. Use ping/pong frames as a Heartbeat to detect them and to keep proxies from culling the connection.
- Reconnection is your job. Exponential backoff with jitter, resubscribe, then replay anything missed using a sequence number. Without jitter, a deploy that drops every connection turns into a reconnect storm.
- Deploys drop connections. Drain gracefully. The network topology does change — one of the Fallacies of Distributed Computing.
- Security. Authenticate during the handshake, check the
Originheader, and rate-limit messages.
The frontend half
Receiving messages is easy; rendering them is where real-time UIs fall over. If every message calls setState high in a
React tree, the whole subtree re-renders many times a second. Own the socket in one place, write messages into a store, and
let only the leaf components subscribe — the pattern in Zustand Transient Updates.
In practice
On real-time trading interfaces the lesson was that the socket is rarely the bottleneck; what you do per message is. Batch updates to the frame, drop intermediate values nobody can see, and measure render cost alongside network latency. Underneath, it’s still Message Passing: independent parties exchanging messages instead of sharing state.
- #websockets
- #real-time
- #networking
- #streaming
↩ Linked from (8)
- AJAX PollingGrowing
…SSEs) | server → client | low | one connection per client | feeds, progress, notifications, token streams | | WebSockets | both ways | lowest | one stateful connection | chat, collaboration, games, trading |
- Fallacies of Distributed ComputingEvergreen
A WebSocket will drop. Topology changes every time you deploy, so the client must reconnect with jitter and replay what it missed. A page that fires twenty requests on load is learning fallacy two the hard way. A mobile…
- HeartbeatGrowing
…ng traffic until it passes). Mixing them up is a classic way to cause a restart loop. Long-lived connections: WebSockets use ping/pong frames, and Server-Sent Events (SSEs) streams send comment lines, both to detect dead…
- HTTP Long PollingGrowing
SSE standardised the server-to-client half of this, and WebSockets cover two-way traffic. Long polling remains the fallback when long-lived connections are blocked by corporate proxies, and it's still a sensible choice f…
- Message Delivery SemanticsEvergreen
…the second request returns the first order's confirmation. The same thinking applies to the retry logic in a WebSocket client: replay from a sequence number, and make applying an already-seen update a no-op.
- Message PassingGrowing
…e all cooperative message handling. Distributed systems: queues, event streams and real-time channels such as WebSockets and Server-Sent Events (SSEs) are message passing between machines.
- Server-Sent Events (SSEs)Growing
EventSource reconnects automatically and sends the last event ID it saw (Last-Event-ID), so the server can replay what was missed. With WebSockets you write all of that yourself.
- Zustand Transient UpdatesEvergreen
…rule: a store plus narrow subscriptions beats prop and setState cascades. The transport side of this lives in WebSockets, and the architecture side in Bulletproof React.
↪ Links to (7)
Related by topic
- Growingmetaphor
Balance Is a Control Loop
Calisthenics Lab - Seedmetaphor
Regress, Don't Grind: Graceful Degradation
Calisthenics Lab - Evergreen
Architecture Decision Records
Career - Growingcase study
Building a Graph Component Library
Frontend craft