skip to content

WebSockets

11 roadmaps45 questionsupdated

One TCP connection that either end may write to at any moment, obtained by upgrading an ordinary HTTP request and then held open. Interviewers reach for it whenever a brief says the word live.

on this pageshow

guide

overview

~1 min

A WebSocket is one long-lived TCP connection, opened by upgrading an HTTP request, over which either side may send a message whenever it likes. Interviewers bring it up whenever a design brief says live or push, to find out whether you know what the protocol leaves to you. A strong answer treats the socket as a thin pipe: it carries messages, while delivery confirmation, matching replies to requests, backpressure, reconnection and authorization after the open are the application's job. The hub splits the way a connection lives. The [HTTP upgrade handshake](/topics/proto-websockets-handshake) and the [extended CONNECT bootstrap](/topics/proto-websockets-http2-http3) are how a socket opens over HTTP/1.1 and over HTTP/2 or HTTP/3. [Frame format and masking](/topics/proto-websockets-framing) is the wire format; [bidirectional messaging](/topics/proto-websockets-messaging) is what the application sees on top of it, and [subprotocols and extensions](/topics/proto-websockets-subprotocols) is how both ends agree on what messages mean. [Ping/pong and close](/topics/proto-websockets-keepalive) covers liveness and shutdown. [Connection authentication](/topics/proto-websockets-auth) and [origin, TLS and proxies](/topics/proto-websockets-scaling) hold the security and deployment questions, and [short and long polling](/topics/proto-websockets-vs-polling) is the baseline a socket is measured against. Junior rounds ask for the handshake, the frame types and the difference from polling. Senior and principal rounds move to production: a proxy that swallows the upgrade, a token in the logs, a consumer that cannot keep up, a fleet where an open connection is the wrong call. Learn the handshake and framing first, then messaging and close; authentication and proxies make sense once the life of a connection is clear.

primer

### It starts as HTTP, then stops being HTTP The opening exchange is an ordinary HTTP request asking to switch protocols. Once the server agrees, the same TCP connection carries WebSocket frames and HTTP has no further say. That reuse is why sockets pass through existing ports and load balancers, and why every HTTP-era concern — cookies, `Origin`, proxies, access logs — applies to that single request and to nothing that follows it. ### Messages, not calls Either end may send at any time, and nothing pairs a message with a reply. The protocol gives you text and binary messages and stops there: no identifiers, no acknowledgements, nothing that confirms arrival. Anything shaped like a call — did the command land, which reply belongs to it — is a convention the two ends invent, which is why interviewers push toward a published subprotocol over a home-grown envelope. ### Frames are the unit on the wire A message travels as one or more frames, each with its own small header. Fragmentation lets a sender stream a message whose size it does not yet know, and lets control frames (ping, pong, close) slip in between pieces. Frames from client to server are masked, a defence aimed at intermediaries rather than eavesdroppers; confidentiality comes from TLS alone. ### Nothing tells the sender to slow down The protocol has no window or credit of its own. When a receiver falls behind, TCP pushes back and the pressure shows up as data piling up inside the sending process. Bounded queues, dropping or coalescing stale updates and caps on inbound message size are designs you choose, not settings you switch on. ### A quiet socket proves nothing A connection whose peer has vanished looks exactly like a healthy idle one until a write fails. Liveness needs a periodic probe with a deadline; a clean ending needs both sides to exchange close frames. ### Authorization happens once, at the door The browser API gives a page no way to add headers to the upgrade, so credentials ride in a cookie, the URL, a pre-minted ticket or the subprotocol list — each with its own leak or forgery risk. Whatever you pick is checked when the socket opens, and a socket that lives for hours outlives that check unless you design for it.

101 Switching Protocols
The HTTP/1.1 status a server returns to accept the upgrade; from the end of that response onward, the connection carries WebSocket frames.
Sec-WebSocket-Accept
The server's handshake field derived from the client's random key. It shows the responder understood the WebSocket handshake; it authenticates nobody.
Frame
The unit on the wire: a short header with FIN bit, opcode, mask flag and payload length, followed by the payload.
Masking
XOR-ing each client-to-server payload with a random per-frame key, so crafted bytes cannot pass for other protocols in proxy caches. Not encryption.
Control frame
A ping, pong or close frame: small, never fragmented, and allowed to arrive between the fragments of a data message.
Close status code
A numeric reason carried in a close frame, such as normal closure or message too big. Some codes exist only for local APIs.
Half-open connection
A connection one side still believes is open after the other side or a middlebox has discarded it; only a write or probe exposes it.
Subprotocol
An application protocol negotiated in the handshake, such as STOMP or MQTT, that defines what messages mean on this socket.
permessage-deflate
The standard extension that compresses message payloads, negotiated with parameters that trade compression ratio against per-connection memory.
wss
The WebSocket scheme run over TLS, on port 443 by default. Protection ends wherever TLS is terminated.
Origin header
The request field a browser sets to the page's origin on the upgrade. Servers check it to block cross-site sockets; non-browser clients can forge it.
Extended CONNECT
The HTTP/2 and HTTP/3 method for opening a WebSocket on one stream, enabled by a server setting, with a success status instead of 101.

Trace one connection from open to close. The client sends an HTTP request asking to upgrade, offering subprotocols and extensions and carrying whatever credential it can: usually a cookie, or a ticket in the URL. Every proxy on the path has to pass that upgrade through, and the server checks `Origin`, the credential and its own connection limits before agreeing. Over HTTP/2 or HTTP/3 the same negotiation rides an extended CONNECT on one stream of a connection that already exists, and a success status stands in for the 101. Once open, the layers stack like this: - **TCP, or one stream of an HTTP/2 or HTTP/3 connection,** carries the bytes and supplies the only backpressure. - **TLS**, for `wss`, encrypts up to the point where it is terminated. - **Frames** carry payload, fragmentation and the control traffic: ping, pong and close. - **Extensions** such as permessage-deflate transform payloads, as agreed at open. - **The subprotocol** gives messages meaning: commands, subscriptions, acknowledgements, errors. - **The application** owns the rest: correlating replies, reconnecting, catching up on missed events, re-checking authorization. In a browser, the page holds only the thin end of all this — a URL, the names it offers and a few events: ```javascript // an ordinary authenticated request mints a short-lived, single-use ticket const { ticket } = await (await fetch("/ws-ticket", { method: "POST" })).json(); // the upgrade takes only a URL and subprotocol names: no header slot const ws = new WebSocket(`wss://example.com/live?ticket=${ticket}`, ["v12.stomp"]); ws.onopen = () => console.log(ws.protocol); // the one name the server echoed ws.onclose = (e) => console.log(e.code); // 1006 when no close frame arrived function send(frame) { if (ws.bufferedAmount > 1_000_000) return; // the page's only backpressure signal ws.send(frame); } ``` Three sections meet in those lines: the credential cannot travel as a header, the server picks at most one subprotocol, and the page learns the receiver is slow only by watching its own send buffer grow.

  1. HTTP Upgrade Handshake →

    Where every connection begins: how an HTTP request becomes a socket, and why HTTP has no say once it succeeds.

  2. Frame Format and Masking →

    The wire format every later section assumes: frame header, message fragmentation and why client frames are masked.

  3. Bidirectional Messaging →

    What the application actually gets: text and binary messages, reassembly, and no built-in flow control or reply matching.

  4. Ping/Pong and Close →

    How to tell a live socket from a dead one and how to end a connection cleanly.

  5. Connection Authentication →

    Credentials on a socket, where tokens leak, and what to do when authorization expires mid-connection.

  6. Origin, TLS, and Proxies →

    Origin checks, TLS and reverse proxies: the reasons a socket that works locally fails once deployed.

  • Calling masking a security feature for the data: the key travels in the frame, anyone on the path can undo it, and only wss keeps payloads private.

  • Assuming a sent message was received and processed: the protocol confirms nothing, so command traffic needs acknowledgements and a correlation id defined by the application or its subprotocol.

  • Treating an allowlisted Origin as authentication: it stops other sites' pages in a victim's browser, while any scripted client sends whatever value it likes.

  • Putting a long-lived access token in the wss: query string, where it lands in logs and history — see Token in the Query String.

  • Reading a quiet connection as a healthy one: without pings on a timer and a pong deadline, a half-open socket stays connected until a write finally fails.

  • Debugging the application when clients get 200 instead of 101 behind a new reverse proxy; the proxy usually dropped the hop-by-hop upgrade fields.

  • Reaching for a socket whenever a brief says real time: for rare updates, one-way push or devices that sleep, polling can be cheaper and simpler.

This guide assumes the protocol as RFC 6455 defined it in 2011, version 13 — the value clients send in `Sec-WebSocket-Version` today. The framing and the HTTP/1.1 handshake have not changed since; what changed is around them, and interviewers ask about each piece: - **RFC 7692** (2015) standardised permessage-deflate and its context-takeover and window parameters. - **RFC 8441** (2018) defined how to open a socket over HTTP/2 with extended CONNECT, gated by a server setting. - **RFC 9220** (2022) carried the same bootstrap to HTTP/3. Pre-standard drafts used a different handshake and sent unmasked frames; they matter now only as the reason masking and the accept digest exist. When a question concerns opening a socket, say which HTTP version you mean: the key and accept exchange and the 101 status belong to HTTP/1.1 alone, and an answer that assumes them on HTTP/2 is wrong.

Interviewers expect you to place WebSockets among the other ways to get data to a client without being asked. **Short and long polling** use plain HTTP and fit rare or bursty updates, especially where clients sleep or connections are metered. **Server-sent events** stream from server to client over an ordinary HTTP response, with reconnection built into the browser API; they fit one-way feeds, and a socket earns its place when the client also sends often. **WebTransport**, built on HTTP/3, offers multiple streams and unreliable datagrams, and is the newer option where head-of-line blocking matters. gRPC streaming serves service-to-service streams more often than browsers. On top of the socket sit the protocols that give messages meaning: STOMP, usually in front of a message broker; MQTT for devices; and graphql-ws for GraphQL subscriptions. Libraries such as Socket.IO add their own protocol with rooms, acknowledgements and fallbacks, so their clients do not talk to a plain WebSocket server. Fanning messages out across a fleet of socket servers is a system-design question; this hub stops at one server's sockets.

report an issue with this guide →

questions

page 2 of 2

When a WebSocket authorized at open is still accepting commands an hour after its credential expired, what are your options?

level: seniorimportance: should knowfreq 48%

basics

~20 s

Three, and they are the whole list: re-authenticate in band over the open socket, close the connection when the credential expires, or cap connection lifetime so a socket never outlives the credential that opened it.

open as a page

A sign controller sends one 8 MB WebSocket binary frame; why does a ping control frame wait behind it?

level: seniorimportance: should knowfreq 38%

basics

~20 s

A control frame may be sent between the frames of a fragmented message, never inside one. An unfragmented 8 MB frame holds the wire until its last payload byte, so the ping queues behind it. Fragmenting the payload creates the gaps a control frame needs.

open as a page

What must a WebSocket client do when a 101 response arrives whose Sec-WebSocket-Accept does not match the key it sent?

level: seniorimportance: should knowfreq 48%

basics

~20 s

It must fail the WebSocket connection: stop, close the underlying connection, and never read the following bytes as protocol data. A wrong or absent digest means whatever answered did not perform this handshake for this connection.

open as a page

A WebSocket bootstrap over HTTP/2 is answered with `:status = 501`, so what has the server said and what should the client do next?

level: seniorimportance: should knowfreq 38%

basics

~20 s

The 501 says the server does not support the :protocol the extended CONNECT carried, so no tunnel opened and no WebSocket exists. A client should stop retrying that path and fall back to the RFC 6455 HTTP/1.1 handshake on a separate connection.

open as a page

A WebSocket to a turbine maintenance console has carried no traffic for an hour and still looks connected; how do you establish whether it is alive?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Send Ping frames on a timer and require a Pong within a deadline. A silent TCP connection cannot distinguish a healthy idle link from one whose state something along the path discarded, so only a probe — judged over several consecutive misses — settles it.

open as a page

A WebSocket endpoint buffers each message's fragments until it is complete. What does a peer sending an enormous message cost it, and how can it refuse?

level: seniorimportance: should knowfreq 40%

basics

~20 s

A fragmented WebSocket message declares no total length, so an unbounded reassembly buffer is a memory-exhaustion vector: one peer, one message. Count bytes as fragments arrive and close with status 1009 once the running total passes your limit.

open as a page

A cue desk holds 40,000 WebSocket connections with `permessage-deflate` on and memory climbs per socket — which negotiated parameters change that, and what do you give up?

level: seniorimportance: should knowfreq 34%

basics

~20 s

By default each endpoint keeps its deflate context between messages, so every socket holds compressor state in each direction. server_no_context_takeover and client_no_context_takeover reset it per message, and the max_window_bits parameters shrink it; both cost compression ratio.

open as a page

Would you standardise a WebSocket fleet on extended CONNECT bootstrapping when each console holds one leased HTTP/2 link and some intermediaries refuse it?

level: principalimportance: should knowfreq 30%

basics

~20 s

Prefer it, but never as the only path. Extended CONNECT puts the socket on a link you already pay for, while support is decided by every hop between the console and the origin - so the fleet commits to both bootstraps and to measuring which one each site actually gets.

open as a page

Your fleet of metered, sleeping field controllers reports twice an hour and the team wants persistent connections; how do you decide?

level: principalimportance: should knowfreq 42%

basics

~20 s

Price freshness against change rate before picking a transport. A device that sleeps on a metered link and speaks twice an hour cannot hold anything open, and a connection that is idle 99% of its life buys latency nobody asked for.

open as a page

How do clients smuggle a bearer token through Sec-WebSocket-Protocol on a WebSocket upgrade, and what must the server echo?

level: middleimportance: nice to knowfreq 28%

basics

~20 s

The client offers two values — the real subprotocol name and a second value carrying the token — because the page can control that list. The server must select exactly one to echo, and it must be the subprotocol name, never the token.

open as a page

What does a server send when a WebSocket upgrade request names a Sec-WebSocket-Version it does not support?

level: middleimportance: nice to knowfreq 31%

basics

~20 s

It aborts the handshake and returns an ordinary HTTP error response - the specification names 426 Upgrade Required - carrying a Sec-WebSocket-Version field that lists every version it is willing to speak. The client may retry with one of them.

open as a page

After a WebSocket endpoint has sent its close frame, what may it still do before the connection is finished?

level: middleimportance: nice to knowfreq 26%

basics

~20 s

It may still receive. After sending a close frame an endpoint must not send any further data frames, but it can go on reading until the peer's close frame arrives, so messages already in flight may still arrive.

open as a page

A WebSocket client needed an extension the server did not return: which close code does it send, and why does no server send it?

level: middleimportance: nice to knowfreq 24%

basics

~20 s

The client sends WebSocket close code 1010, which means it expected the server to negotiate one or more extensions and the server did not. A server never needs it: it can refuse the opening handshake instead of accepting and then closing.

open as a page

How does a WebSocket carried in an extended CONNECT tunnel over HTTP/2 or HTTP/3 end, and what survives that ending?

level: seniorimportance: nice to knowfreq 29%

basics

~20 s

The stream ends, not the connection. In HTTP/2 each side finishes with a DATA frame carrying END_STREAM; in HTTP/3 with a FIN on that stream. The connection and every other exchange riding it continue untouched.

open as a page

When a server hits the operator-set cap on concurrent WebSocket connections it will hold, what does the next client actually observe?

level: seniorimportance: nice to knowfreq 33%

basics

~20 s

A failed handshake, not a closed socket. The refusal lands while the exchange is still HTTP — an error status instead of 101 Switching Protocols — or, enforced lower down, a connection dropped with no response at all.

open as a page

showing 31–45 of 45