Skip to content

Top 30 WebSocket Interview Questions and Answers [2026]

October 2, 2026 16 min read
WebSocket interview guide by Second Talent
TL;DR: WebSocket interviews in 2026 test the RFC 6455 handshake and framing, heartbeats and reconnection, scaling across servers with a pub/sub backplane, and security checks such as Origin validation. Candidates should know when Server-Sent Events are the simpler choice, and that Node.js 22 ships a stable built-in WebSocket client.

Node.js 22.4.0, released on July 2, 2024, marked its built-in WebSocket client stable, so Node code no longer needs a package to connect to a socket. The protocol itself has not changed since RFC 6455 in 2011.

What has changed is the tooling around it: stream-based APIs with backpressure, and WebSockets over HTTP/2 and HTTP/3. Most interviews still turn on handshakes, dead connections and scaling.

Key takeaways
  1. 1Chrome 124 shipped WebSocketStream, a stream-based API with backpressure. MDN still marks it experimental and non-standard.
  2. 2.NET 10 added its own WebSocketStream, which exposes a socket as a normal Stream.
  3. 3Python's websockets 14.0 made its new asyncio implementation the default; version 17.0 now needs Python 3.11 or later.
  4. 4Socket.IO is not a WebSocket implementation: a plain WebSocket client cannot talk to a Socket.IO server.

Protocol Basics

1. What is WebSocket, and when is it better than HTTP polling?

WebSocket is a protocol for a long-lived, two-way connection between a client and a server over one TCP connection, defined in RFC 6455. After a one-time HTTP handshake, either side can send a message at any moment without a new request.

It beats polling when updates are frequent and latency matters, such as chat, multiplayer games, trading screens or shared editing.

Polling sends a full HTTP request each time, even when nothing changed, and the delay is at least the poll interval. For rare updates, polling is simpler and works with ordinary HTTP caching and load balancing.

2. Walk through the opening handshake.

The client sends an HTTP/1.1 GET with Upgrade: websocket, Connection: Upgrade, a random Sec-WebSocket-Key and Sec-WebSocket-Version: 13. Browsers also send Origin.

If the server accepts, it replies 101 Switching Protocols with a Sec-WebSocket-Accept header.

Five steps of the WebSocket opening handshake: the client sends a GET with Upgrade and Sec-WebSocket-Key, the server checks Origin and credentials, replies 101 with Sec-WebSocket-Accept, the client verifies it, and frames flow both ways.
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://example.com

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

From then on, the TCP connection carries WebSocket frames, not HTTP. Any other status code means the upgrade failed, and the connection stays plain HTTP.

3. How is Sec-WebSocket-Accept computed, and what is it for?

The server appends the fixed GUID 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 to the client's key, takes the SHA-1 hash, and base64-encodes the result. The client checks that value and fails the connection if it is wrong.

It is not security or authentication. It proves the server understood the WebSocket handshake, rather than being an HTTP server or cache that echoed a response by accident.

A candidate who calls it a security feature has mixed it up with authentication.

4. What is in a WebSocket frame?

A frame has a small header and a payload. The header holds:

  • FIN: set on the last frame of a message.
  • Opcode: 0x1 text, 0x2 binary, 0x0 continuation, 0x8 close, 0x9 ping, 0xA pong.
  • MASK bit and a 4-byte masking key, set on every frame from client to server.
  • Payload length: 7 bits, or 126 followed by a 16-bit length, or 127 followed by a 64-bit length.

Control frames (close, ping, pong) carry at most 125 bytes of payload and cannot be fragmented. That lets them be sent between the fragments of a large message.

5. Why must frames from the client be masked?

Masking protects proxies and caches in the middle, not the payload. A browser runs code written by untrusted websites.

Without masking, a script could shape frame bytes to look like an HTTP request, and a confused proxy could cache a poisoned response.

The client XORs the payload with a fresh random key per frame, so the script cannot control the bytes on the wire. It is not encryption: the key travels in the frame.

A server must close the connection if a client frame arrives unmasked, and server frames are never masked.

6. What is the difference between text and binary messages, and what is fragmentation?

A text message must be valid UTF-8, and the receiver must fail the connection if it is not. A binary message can hold any bytes, which suits Protocol Buffers, MessagePack or compressed data.

Fragmentation splits one message across several frames: the first frame has the real opcode and FIN unset, the rest use the continuation opcode, and the last sets FIN. It lets a sender stream a message whose size it does not know yet.

Most application code never sees fragments, because libraries join them into one message.

7. What are ping and pong for, and why do apps add their own heartbeat?

Ping and pong are control frames for checking that the other side is alive. When one side receives a ping, it must answer with a pong carrying the same payload. Servers send pings on a timer and close connections that stop answering.

The browser WebSocket API does not expose ping frames to JavaScript. Browsers answer pings on their own, but page code cannot send one or see one arrive.

So a browser client that wants to detect a dead server sends its own small heartbeat message and expects a reply. Heartbeats also keep proxies and load balancers from closing a connection they think is idle.

8. How does a connection close, and which close codes should you know?

Either side sends a close frame with a code and optional reason, the other side replies with its own close frame, and then the TCP connection is closed. The common codes:

  • 1000: normal closure.
  • 1001: going away, such as a server restart or a page being closed.
  • 1008: policy violation, for example a failed auth check.
  • 1009: message too big.
  • 1011: the server hit an unexpected error.
  • 1006: abnormal closure, meaning no close frame arrived. It is never sent on the wire; the client reports it locally.

A client that sees 1006 should treat it as a network failure and reconnect with backoff.

9. What are subprotocols and extensions?

A subprotocol names the message format the app speaks on top of WebSocket. The client lists options in Sec-WebSocket-Protocol, such as graphql-transport-ws or mqtt, and the server picks one.

A server can refuse a client that offers none it supports.

Extensions change the framing itself. The common one is permessage-deflate from RFC 7692, which compresses each message. It saves bandwidth for repetitive JSON. The costs are CPU time and memory for a compression context on each connection.

With many thousands of connections, that memory adds up.

Choosing a Transport

10. When would you pick Server-Sent Events over WebSocket?

Pick Server-Sent Events (SSE) when data flows only from server to client, such as notifications, live scores or streamed AI responses. SSE is plain HTTP, so it works with existing auth, proxies and HTTP/2.

The browser's EventSource reconnects on its own and can resume from the last event ID.

Two-by-two grid for choosing a real-time transport: Server-Sent Events for frequent server-to-client updates, WebSocket for frequent two-way traffic, polling for occasional status checks, and plain HTTP requests for occasional commands.

Pick WebSocket when the client also sends frequent messages, as in chat, games or shared editing. SSE also sends text only, while WebSocket supports binary.

Over HTTP/1.1, browsers limit the number of connections per domain, which caps how many SSE streams one page can open. See MDN's Server-sent events page.

Server-Sent Events
  • Server to client only
  • Plain HTTP; text messages
  • Built-in reconnect and last event ID
WebSocket
  • Both directions on one connection
  • Text and binary messages
  • Reconnect and resume are up to you

11. What does Socket.IO add, and why can't a WebSocket client talk to it?

Socket.IO is a library with its own protocol on top of WebSocket or HTTP long polling. It adds automatic reconnection, acknowledgements, rooms, namespaces and a fallback when WebSocket is blocked.

The Socket.IO docs say plainly that it is not a WebSocket implementation. It adds metadata to each packet, so a plain WebSocket client cannot connect to a Socket.IO server, and the reverse is also true.

Choosing it ties the client and server to one library. That is a fair trade for its features, but it should be a deliberate choice.

12. Can WebSockets run over HTTP/2 or HTTP/3?

Yes. RFC 8441 defines WebSockets over HTTP/2, and RFC 9220 does the same for HTTP/3. Instead of the Upgrade header, the client uses an extended CONNECT request with :protocol: websocket.

The server must first advertise support with the SETTINGS_ENABLE_CONNECT_PROTOCOL setting.

The gain is that a WebSocket becomes one stream inside a shared connection, so it skips a separate TCP and TLS setup. Support varies across browsers, servers and proxies. Code should expect a plain HTTP/1.1 upgrade as the fallback.

Reliability

13. How should a client reconnect after a drop?

With exponential backoff and random jitter, and with a cap. Retry after about 1 second, then 2, 4 and 8, up to a maximum such as 30 seconds. Add a random offset to each delay.

function nextDelay(attempt) {
  const base = Math.min(30_000, 1_000 * 2 ** attempt);
  return base / 2 + Math.random() * (base / 2);   // jitter
}

Jitter matters most after a server restart. Without it, every client reconnects at the same instant, and the load can knock the new server over again.

Reset the attempt counter only after a connection has stayed up for a while, not right after the handshake.

14. Does WebSocket guarantee delivery?

No. Within one connection, TCP delivers messages in order and without gaps. But when a connection drops, messages in flight or queued in buffers are lost, and neither side knows exactly which ones arrived.

Apps that need delivery add it themselves. The server gives each message a sequence number. The client acknowledges what it processed, and after reconnecting it asks to resume from the last number it saw.

The server keeps a short history, often in Redis Streams or Kafka, to replay the gap. Messages should also be safe to receive twice.

15. What is backpressure, and how do you handle a slow client?

Backpressure means a fast sender slows down when the receiver cannot keep up. The classic browser WebSocket API has none on the receive side. On the send side it exposes only bufferedAmount, the bytes queued but not yet sent.

On the server, one slow client on a bad mobile link can make its send queue grow until the process runs out of memory. Every connection needs a bounded outgoing queue.

When it fills, drop old messages if they are replaceable, such as price ticks, or close the connection with a clear code. This is the gap the newer stream-based APIs aim to close.

16. How do you detect a connection that is dead but still looks open?

Send periodic pings or heartbeats and close the connection when no reply arrives within a timeout. A TCP connection can be "half-open": the other side vanished, for example when a phone lost signal, but no packet announced it.

Without a heartbeat, the server keeps that connection, its memory and its subscriptions until the operating system's TCP timeout, which can take far longer.

Check the idle timeouts on every proxy and load balancer in the path, and send heartbeats more often than the shortest one.

Scaling

17. How do you scale WebSockets across several servers?

Add a pub/sub backplane so a message published on one server reaches clients connected to any server. Redis pub/sub, NATS and Kafka are common choices.

Each server subscribes to the channels its clients care about and forwards messages to their sockets.

A common myth says plain WebSockets need sticky sessions. They do not: a WebSocket is one long TCP connection, so it stays on the server that accepted it.

Sticky sessions matter for protocols with an HTTP long-polling fallback, like Socket.IO. Its multiple nodes guide explains that every polling request must reach the same process.

Balance connections, not requests. A load balancer that picks the server with the fewest connections spreads long-lived sockets better than round robin. Round robin can leave new servers nearly empty after a scale-out.

18. What limits how many connections one server can hold?

Memory and file descriptors, far more than CPU. Each connection holds kernel socket buffers, library buffers, and app state such as subscriptions and user data. Compression contexts from permessage-deflate add more.

Other limits appear at scale: the process's open-file limit, the load balancer's own connection limits, and ephemeral port exhaustion between the proxy and the backends.

A strong answer measures memory per connection under a realistic load test and sizes servers from that. It does not quote a number from a blog post.

19. How do you deploy without dropping every user at once?

Drain servers gradually. Take the server out of the load balancer so it gets no new connections, then close existing ones with code 1001 over a period of time. Clients reconnect, with jitter, to the servers that remain.

Closing all connections at the same moment causes a reconnect storm. It also re-runs every handshake, auth check and subscription at once.

Clients should restore their subscriptions and resume from their last sequence number after reconnecting, so users see no gap.

20. How would you build rooms and presence?

Keep a map from room ID to the set of local connections in it, and a pub/sub channel per room across servers. Joining adds the connection to the local set and subscribes the server to the room's channel if it is the first local member.

Leaving or disconnecting reverses both steps.

Presence ("who is online") needs shared state, such as a Redis set per room with a time-to-live that heartbeats refresh. A crashed server cannot clean up after itself. Expiring entries remove its users on their own.

Security

21. What is cross-site WebSocket hijacking, and how do you stop it?

Cross-site WebSocket hijacking (CSWSH) happens when a malicious page opens a WebSocket to your server and the browser attaches the victim's cookies.

The same-origin policy does not block WebSocket connections, so the attacker's page can then send and read messages as the victim.

The fix is to check the Origin header during the handshake against an allowlist, and reject anything else. Tokens that the page must send explicitly, rather than cookies alone, add a second layer.

The OWASP WebSocket Security Cheat Sheet covers both.

22. How do you authenticate a browser WebSocket?

The browser WebSocket constructor cannot set custom headers, so a normal Authorization: Bearer header is not an option. The common patterns are:

  • Cookies sent with the handshake, plus a strict Origin check.
  • A short-lived ticket in the query string, fetched from an authenticated HTTP endpoint right before connecting. Query strings end up in logs, so the ticket must expire in seconds and work once.
  • A token in the first message, with the server closing the connection if it does not arrive quickly.

Putting a long-lived access token in the URL is the answer to push back on.

23. What happens when a token expires on a connection that stays open for hours?

Nothing, unless you design for it. The handshake is checked once, so a connection can outlive the token, the session, or even the user's access. The server must re-check on its own.

Options include closing connections when the token's expiry passes, asking the client to send a fresh token over the socket, or checking permissions per subscription and per sensitive message.

When an admin removes a user's access, the system must also close that user's open sockets.

24. Which limits should every WebSocket server enforce?

Limits on message size, message rate and connection count. Without them, one client can send a huge message that fills memory, or flood the server with small ones.

  • A maximum message size, enforced before buffering the whole message.
  • A per-connection message rate, with a close code such as 1008 when it is exceeded.
  • A limit on connections per user or IP, and on subscriptions per connection.
  • Schema validation of every message, the same as any HTTP body.
  • wss:// only, so traffic is encrypted and proxies are less likely to interfere.

25. How do you test WebSocket code?

Test the message handling logic as plain functions, then run integration tests against a real server on a local port. Most libraries let a test start a server and connect a client in the same process.

The cases that catch real bugs are the unhappy ones. Test a drop in the middle of a message stream, a reconnect with resume, a client that never reads, a malformed message and an expired token.

Load tests need tools that hold many open connections, such as k6 or Artillery, not tools built for short HTTP requests.

What Changed Recently

Apr 24, 2024
Node.js 22.0: built-in WebSocket client on without a flag
Jul 2, 2024
Node.js 22.4: WebSocket client no longer experimental
Nov 9, 2024
Python websockets 14.0: new asyncio implementation by default
Nov 11, 2025
.NET 10: WebSocketStream; ASP.NET Core adds SSE results
Jul 29, 2026
Python websockets 17.0: requires Python 3.11 or later

26. What changed for WebSocket clients in Node.js?

Node.js now has a browser-compatible WebSocket class as a global. Per the Node.js globals docs, it was added in v21, left the --experimental-websocket flag in v22.0.0, and stopped being experimental in v22.4.0.

const ws = new WebSocket("wss://example.com/feed");
ws.addEventListener("message", (e) => console.log(e.data));

It is a client only. Node still has no built-in WebSocket server, so servers keep using libraries such as ws or a framework. The benefit is that the same client code runs in browsers and in Node.

27. What is WebSocketStream in the browser?

WebSocketStream is a promise- and stream-based alternative to the WebSocket API, and its main addition is backpressure. Reading from its readable stream only pulls messages as fast as the page processes them.

Chrome enabled it by default in version 124.

MDN's WebSocketStream page still marks it experimental and non-standard, so production code must check for it and fall back to WebSocket. A candidate who mentions it when asked about backpressure is following the platform closely.

28. What did .NET 10 add for WebSockets?

.NET 10 added WebSocketStream, which wraps a WebSocket as a standard Stream. Per the .NET 10 libraries notes, the aim is to cut the manual buffering and framing code that common WebSocket tasks needed.

With a Stream, a socket can be passed straight to a StreamReader, a JSON deserializer or a pipe. Before, reading one message meant looping over ReceiveAsync until EndOfMessage and joining buffers by hand.

29. What changed in Python's websockets library?

Version 14.0, released on November 9, 2024, made the library's new asyncio implementation the default and deprecated the legacy one.

The changelog says code that imports connect or serve from the top-level package must follow the upgrade guide, or import the legacy module explicitly.

Later releases kept moving. 16.0 added support for free-threaded Python. 17.0, on July 29, 2026, requires Python 3.11 or later and makes several boolean arguments keyword-only.

A service pinned to an old version and old Python has an upgrade to plan.

30. What should a team check before adopting WebSockets over HTTP/2?

Check every hop. The browser, any CDN, the load balancer and the application server must all support the extended CONNECT method from RFC 8441.

If one hop does not, the connection falls back to an HTTP/1.1 upgrade, or fails if fallback is not configured.

Also check how the server limits streams per connection. Many WebSockets sharing one HTTP/2 connection means one slow stream can compete with others for the same flow-control window. Measure before and after rather than assuming a speedup.

Signs of a Strong Answer

  • They say that Sec-WebSocket-Accept and masking are not security features, and explain what each one is for.
  • They add jitter to reconnect backoff and can describe the reconnect storm without it.
  • They correct the sticky-session myth for plain WebSockets but know why Socket.IO needs it.
  • They bound the outgoing queue per connection and say what happens to a slow client.
  • They check Origin on the handshake and re-check authorization on long-lived connections.
  • They reach for SSE when traffic only flows from server to client.

Hiring WebSocket Developers

Real-time systems need engineers who have debugged dead connections and reconnect storms in production, not only built a demo chat app.

Second Talent matches companies with pre-vetted back-end engineers from Asia with real-time experience, screened with questions like these.

Tell us the stack and we send a shortlist within 24 hours. Start hiring, or see our Node.js and Redis interview guides.

Hiring developers in Southeast Asia?

Get Cost Guide

How would you like to talk?

WhatsApp us Prefer texting at your own pace? Just hit us up on WhatsApp. We promise no spam and a hassle-free experience.

Loading available times…