WebSockets
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 pageshowhide
guide
overview
~1 minA 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.
- HTTP Upgrade Handshake →
Where every connection begins: how an HTTP request becomes a socket, and why HTTP has no say once it succeeds.
- Frame Format and Masking →
The wire format every later section assumes: frame header, message fragmentation and why client frames are masked.
- Bidirectional Messaging →
What the application actually gets: text and binary messages, reassembly, and no built-in flow control or reply matching.
- Ping/Pong and Close →
How to tell a live socket from a dead one and how to end a connection cleanly.
- Connection Authentication →
Credentials on a socket, where tokens leak, and what to do when authorization expires mid-connection.
- 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
wsskeeps 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
Originas 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.
explore
- HTTP Upgrade Handshake4 questions
- Extended CONNECT Bootstrap5 questions
- Frame Format and Masking5 questions
- Bidirectional Messaging6 questions
- Subprotocols and Extensions5 questions
- Ping/Pong and Close4 questions
- Origin, TLS, and Proxies5 questions
- Short and Long Polling5 questions
- Connection Authentication6 questions
- Backend Developerroleanchors this topic
- Full Stack Developerroleanchors this topic
- GraphQLskillanchors this topic
- Java Backend Developerroleanchors this topic
- Kotlin Backend Developerroleanchors this topic
- AI Red Teamingrole
- API Designskill
- Computer Scienceskill
- Forward Deployed Engineerrole
- Server-Side Game Developerrole
- Software Architectrole
questions
page 2 of 2When a WebSocket authorized at open is still accepting commands an hour after its credential expired, what are your options?
basics
~20 sThree, 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.
A sign controller sends one 8 MB WebSocket binary frame; why does a ping control frame wait behind it?
basics
~20 sA 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.
What must a WebSocket client do when a 101 response arrives whose Sec-WebSocket-Accept does not match the key it sent?
basics
~20 sIt 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.
A WebSocket bootstrap over HTTP/2 is answered with `:status = 501`, so what has the server said and what should the client do next?
basics
~20 sThe 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.
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?
basics
~20 sSend 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.
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?
basics
~20 sA 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.
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?
basics
~20 sBy 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.
Would you standardise a WebSocket fleet on extended CONNECT bootstrapping when each console holds one leased HTTP/2 link and some intermediaries refuse it?
basics
~20 sPrefer 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.
Your fleet of metered, sleeping field controllers reports twice an hour and the team wants persistent connections; how do you decide?
basics
~20 sPrice 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.
How do clients smuggle a bearer token through Sec-WebSocket-Protocol on a WebSocket upgrade, and what must the server echo?
basics
~20 sThe 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.
What does a server send when a WebSocket upgrade request names a Sec-WebSocket-Version it does not support?
basics
~20 sIt 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.
After a WebSocket endpoint has sent its close frame, what may it still do before the connection is finished?
basics
~20 sIt 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.
A WebSocket client needed an extension the server did not return: which close code does it send, and why does no server send it?
basics
~20 sThe 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.
How does a WebSocket carried in an extended CONNECT tunnel over HTTP/2 or HTTP/3 end, and what survives that ending?
basics
~20 sThe 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.
When a server hits the operator-set cap on concurrent WebSocket connections it will hold, what does the next client actually observe?
basics
~20 sA 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.
showing 31–45 of 45