Networking
WebSocket
HTTP is one request, one response, then done — a client always has to ask before a server can say anything. WebSocket exists for the opposite need: a connection that stays open, over which either side can send a message at any moment, with no request required first.
- What it is
- A persistent, full-duplex connection over a single TCP connection, started via a normal HTTP handshake.
- Mental model
- A phone call instead of exchanging postcards — once connected, either side can speak whenever it wants, with no need to wait for a question first.
- Key numbers
ws://(plaintext, like port 80) orwss://(encrypted, like port 443) — begins life as an ordinary HTTP request.- Reach for it when
- A server needs to push data to a client the moment something changes, without the client repeatedly asking "anything new yet?"
Born from one HTTP request
A WebSocket connection starts as an ordinary HTTP GET request carrying two special headers —
Upgrade: websocket and Connection: Upgrade — asking the server to repurpose
this same TCP connection for something other than HTTP. If the server agrees, it replies with status
101 Switching Protocols (the one practical use of HTTP's rarely-seen 1xx status range),
and from that exact point on, the connection stops speaking HTTP entirely and starts speaking the
WebSocket framing protocol instead.
Full-duplex — a genuine two-way street
Once upgraded, there's no more request/response pairing at all. The server can push a message the instant it has something new; the client can send one without prompting. Neither side is "waiting for a reply" the way HTTP structurally requires — both directions are simply open, independently, for as long as the connection lives.
WebSocket vs. polling
Before WebSocket, the only way to approximate "near real-time updates" over HTTP was polling — the client repeatedly sends a GET every few seconds, and the server answers "nothing new" almost every time. This wastes a full request/response cycle on every empty check, and caps how fresh the data can ever be at the polling interval. WebSocket removes both costs at once: no wasted empty requests, and updates arrive the instant the server has one to send, not up to N seconds later.
The cost: a stateful connection
HTTP's statelessness (see HTTP) is what lets any request be freely routed to any server behind a load balancer. A WebSocket connection breaks that assumption — once open, it's pinned to one specific server process for its entire lifetime, since the connection itself is the state. Scaling a WebSocket-heavy service means thinking about connection distribution and server affinity in a way a purely stateless HTTP API never has to.
Real-world applications
- Live IoT dashboards — a web dashboard showing sensor readings update the instant a device reports new data, rather than refreshing on a timer.
- Chat and collaborative editing — both directions need to push updates with minimal latency, the canonical WebSocket use case.
- Financial ticker feeds — continuously changing values pushed to every connected client the moment they change.
- Some multiplayer game state sync — though the most latency-critical games often go further and use raw UDP directly, accepting occasional loss in exchange for lower overhead than even a WebSocket frame carries.
Gotchas
- Older or misconfigured proxies that don't understand the
Upgradeheader can silently break a WebSocket handshake — a connection that works directly against a server but fails behind a particular proxy or load balancer is a very common symptom. - A dead WebSocket connection doesn't always fail loudly — an application needs its own periodic ping/pong heartbeat to detect a silently-dropped connection, since neither TCP nor WebSocket itself guarantees prompt failure notification.
- Because a connection is pinned to one server, a server restart or deploy drops every WebSocket client connected to it at once — client-side reconnect logic isn't optional, it's required for a production-quality integration.