Top 60 WebSockets Interview Questions (2026)

The 60 WebSockets questions interviewers actually ask, with direct answers, runnable code, and what the interviewer is listening for. Grouped for freshers, intermediate, and experienced rounds.

60 questions with answers

What Is WebSockets?

Key Takeaways

  • WebSocket is a protocol that gives a browser and server one long-lived, full-duplex TCP connection, so both sides can send messages at any time.
  • It starts as an HTTP request that the server upgrades, then switches to the WebSocket framing protocol over the same TCP socket.
  • Interviews test the handshake, the ws and wss schemes, framing, ping/pong keepalive, and how you'd scale and secure a real-time system, not just the browser API.
  • This page is a question bank: work your tier first, read one tier up, and say answers out loud because delivery is evaluated too.

WebSocket is a communication protocol standardized as RFC 6455 that provides a full-duplex channel over a single TCP connection. A client opens it with an HTTP request carrying an Upgrade: websocket header; if the server agrees, it replies with a 101 Switching Protocols status and the same socket is reused for the WebSocket protocol from then on. After that handshake, either side can push messages whenever it wants, which is what plain HTTP request/response can't do without polling. According to MDN Web Docs, the WebSocket API makes it possible to open a two-way interactive session between the browser and a server, so you can send messages and receive event-driven responses without polling. In interviews, WebSocket questions probe the handshake, the ws:// and wss:// schemes, message framing, ping/pong keepalive, reconnection, and how you'd scale connections across servers, not memorized API calls. This page collects the 60 questions that come up most, each with a direct answer and runnable code. Increasingly the first round is a live AI coding interview, so pair this bank with our AI interview preparation guides for the format side.

60Questions with answers on this page
3Difficulty tiers: freshers, intermediate, experienced
20+Runnable code snippets you can practice from
ws / wssThe two WebSocket URI schemes you must know

Watch: A Beginner's Guide to WebSockets

Video: A Beginner's Guide to WebSockets (freeCodeCamp.org, YouTube)

Test yourself and earn a certificate

10 quick questions. Score 70%+ to download your WebSockets certificate.

Jump to quiz

All Questions on This Page

60 questions
WebSockets Interview Questions for Freshers
  1. 1. What is a WebSocket?
  2. 2. How is a WebSocket different from a normal HTTP request?
  3. 3. What is the difference between ws:// and wss://?
  4. 4. What does full-duplex mean in the context of WebSockets?
  5. 5. How does the WebSocket handshake work?
  6. 6. How do you open a WebSocket connection in the browser?
  7. 7. What are the main events on a WebSocket object?
  8. 8. How do you send and receive data over a WebSocket?
  9. 9. What kinds of applications use WebSockets?
  10. 10. How do you close a WebSocket connection?
  11. 11. What is the readyState property?
  12. 12. Can WebSockets send binary data, or only text?
  13. 13. Does WebSocket use TCP or UDP?
  14. 14. What is Socket.IO and how is it different from WebSocket?
  15. 15. Why use WebSockets instead of polling?
  16. 16. What ports do WebSockets use and why does that help with firewalls?
  17. 17. Does each client keep its own WebSocket connection?
  18. 18. Are WebSocket messages guaranteed to arrive in order?
  19. 19. Do WebSockets follow the same-origin policy and CORS?
  20. 20. Can you write a minimal WebSocket echo server?
WebSockets Intermediate Interview Questions
  1. 21. What is a WebSocket frame and what types exist?
  2. 22. How do ping and pong frames keep a connection alive?
  3. 23. How do you handle reconnection when a WebSocket drops?
  4. 24. How do you detect a dead connection that TCP still thinks is open?
  5. 25. What is back pressure in WebSockets and how do you handle it?
  6. 26. How do you authenticate a WebSocket connection?
  7. 27. How do you broadcast a message to many clients?
  8. 28. How do you implement rooms or channels?
  9. 29. How should you structure messages over a WebSocket?
  10. 30. When would you choose Server-Sent Events over WebSockets?
  11. 31. How many WebSocket connections can a browser open?
  12. 32. What do proxies and load balancers need to support WebSockets?
  13. 33. Why might you need sticky sessions with WebSockets?
  14. 34. Does WebSocket support message compression?
  15. 35. How do you gracefully shut down a WebSocket server for a deploy?
  16. 36. Does WebSocket guarantee a message is delivered and processed?
  17. 37. How do you test WebSocket code?
  18. 38. Why do WebSocket connections sometimes drop after being idle?
  19. 39. What is a WebSocket subprotocol?
  20. 40. How do you add acknowledgements to WebSocket messages?
  21. 41. How do you rate limit messages on a WebSocket connection?
WebSockets Interview Questions for Experienced Developers
  1. 42. How do you scale WebSockets across many servers?
  2. 43. What are the main security risks with WebSockets and how do you mitigate them?
  3. 44. How do WebSockets relate to HTTP/2 and HTTP/3?
  4. 45. What is a half-open WebSocket connection and why is it dangerous?
  5. 46. How do you preserve message ordering across reconnections?
  6. 47. How would you design a presence system (who is online) with WebSockets?
  7. 48. Why must client-to-server WebSocket frames be masked?
  8. 49. How do you load test a WebSocket service?
  9. 50. How do you build a fallback when WebSockets are blocked?
  10. 51. What do you monitor for a production WebSocket system?
  11. 52. A WebSocket feature is flaky in production. Walk through your debugging approach.
  12. 53. What makes scaling WebSockets harder than scaling REST APIs?
  13. 54. How do you handle very large messages over a WebSocket?
  14. 55. How do you keep a session alive across a WebSocket reconnection?
  15. 56. What does raw RFC 6455 WebSocket give you, and what do you always end up adding?
  16. 57. How do GraphQL subscriptions use WebSockets?
  17. 58. What drives the memory and CPU cost of a WebSocket server?
  18. 59. How does Redis pub/sub fan a broadcast out across WebSocket servers?
  19. 60. How do you resume a session and replay missed messages after a reconnect?

WebSockets Interview Questions for Freshers

Freshers20 questions

The fundamentals every entry-level round checks. If any answer here surprises you, that's your study list.

Q1. What is a WebSocket?

A WebSocket is a protocol that opens a single, long-lived, full-duplex connection between a client and a server over one TCP socket. Once it's open, both sides can send messages at any time without a fresh request each time.

It's built for real-time features: chat, live dashboards, notifications, multiplayer games. The connection starts as an HTTP request that the server upgrades, then stays open for two-way messaging.

Key point: Lead with 'full-duplex over one persistent connection' and one real use case. Interviewers open with this to hear whether you understand the shape of the protocol.

Watch a deeper explanation

Video: WebSockets in 100 Seconds & Beyond with Socket.io (Fireship, YouTube)

Q2. How is a WebSocket different from a normal HTTP request?

HTTP is request/response and short-lived: the client asks, the server answers, and the connection is typically done. WebSocket is a persistent, full-duplex connection where the server can push messages to the client without being asked.

HTTP is stateless and cacheable, which suits fetching pages and data. WebSocket keeps state (an open connection per client) and suits continuous two-way messaging where new data arrives on the server's schedule.

HTTPWebSocket
ConnectionShort-lived per requestOne long-lived connection
DirectionClient requests, server respondsFull-duplex, both push
StateStatelessStateful (connection stays open)
Best forPages, REST APIsReal-time, live updates

Key point: The follow-up is almost always 'so when would you still use HTTP?'. Have caching and stateless simplicity ready.

Watch a deeper explanation

Video: What are WebSockets | How is it different from HTTP? (Tech Primers, YouTube)

Q3. What is the difference between ws:// and wss://?

ws:// is a plaintext WebSocket connection; wss:// is a WebSocket over TLS, the encrypted version. wss is to ws what https is to http.

In production you use wss:// so messages can't be read or tampered with in transit, and because pages served over https are only allowed to open secure WebSocket connections. The default ports are 80 for ws and 443 for wss.

javascript
// plaintext, fine for local dev only
const dev = new WebSocket("ws://localhost:8080");

// encrypted, required in production
const prod = new WebSocket("wss://api.example.com/socket");

Key point: Saying 'an https page can't open a ws:// connection, the browser blocks it as mixed content' shows you've hit this in real work.

Q4. What does full-duplex mean in the context of WebSockets?

Full-duplex means both the client and the server can send messages independently, at the same time, over the one connection. Neither side has to wait for the other to finish or to be asked.

This is the core difference from request/response HTTP, which is effectively half-duplex from the app's view: the client asks, then the server answers. With WebSocket a chat message from you and a message from the server can be in flight together.

Q5. How does the WebSocket handshake work?

It starts as a normal HTTP GET request with headers Upgrade: websocket and Connection: Upgrade, plus a random Sec-WebSocket-Key. If the server agrees, it responds with status 101 Switching Protocols and a Sec-WebSocket-Accept header derived from that key.

After the 101 response, the same TCP connection stops speaking HTTP and starts carrying WebSocket frames. So one connection is reused: HTTP for the handshake, then the WebSocket protocol for everything after.

http
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

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

Key point: Naming the 101 status and 'the handshake is HTTP, then it upgrades' is the exact detail the key signal is here.

Watch a deeper explanation

Video: WebSockets Crash Course - Handshake, Use-cases, Pros & Cons and more (Hussein Nasser, YouTube)

Q6. How do you open a WebSocket connection in the browser?

You create a WebSocket object with the server URL, then attach event handlers. The four events are open (connected), message (data arrived), close (connection ended), and error.

send() pushes data to the server, and close() shuts the connection down cleanly. The API is small; most of the real work is handling the lifecycle events well.

javascript
const socket = new WebSocket("wss://example.com/chat");

socket.onopen = () => socket.send("hello server");
socket.onmessage = (event) => console.log("got:", event.data);
socket.onclose = (event) => console.log("closed", event.code);
socket.onerror = (err) => console.error("error", err);

Q7. What are the main events on a WebSocket object?

open fires once when the connection is established. message fires every time data arrives, with the payload in event.data. close fires when the connection ends, carrying a code and reason. error fires on a failure, usually just before a close.

A resilient client wires all four: open to start sending, message to handle data, close to trigger reconnection logic, and error to log. Ignoring close and error is the most common beginner mistake.

  • open: connection ready, safe to send
  • message: data received, read event.data
  • close: connection ended, has code and reason
  • error: something failed, expect a close next

Q8. How do you send and receive data over a WebSocket?

You send with socket.send(data), where data is a string, Blob, or ArrayBuffer. You receive by handling the message event and reading event.data. There's no request/response pairing built in; a message is just a message.

Because there's no built-in shape, apps usually agree on a format. JSON is the common choice: stringify on the way out, parse on the way in, and put a type field on every message so the receiver knows what it got.

javascript
// sending
socket.send(JSON.stringify({ type: "chat", text: "hi" }));

// receiving
socket.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  if (msg.type === "chat") render(msg.text);
};

Q9. What kinds of applications use WebSockets?

Anything where updates need to reach the user the moment they happen, without the user refreshing or the page polling. Chat and messaging, live sports scores and stock tickers, collaborative editors like shared docs, multiplayer games, and live dashboards or notifications.

The common thread is server-driven, low-latency updates. If the server is the one that knows when something changed, a WebSocket pushes it out instantly instead of the client asking again and again.

Q10. How do you close a WebSocket connection?

Call socket.close(), optionally with a close code and a short reason string. The other side gets a close event with that code, and the TCP connection is torn down cleanly.

Code 1000 means normal closure. You can pass application-defined codes in the 4000-4999 range for your own reasons. Always closing cleanly matters because it lets the peer distinguish an intended shutdown from a dropped connection.

javascript
// clean, normal close
socket.close(1000, "user left the page");

// custom app code
socket.close(4001, "session expired");

Q11. What is the readyState property?

readyState tells you what phase the connection is in. It's one of four numeric constants: CONNECTING (0), OPEN (1), CLOSING (2), and CLOSED (3).

You check it before sending, because calling send() on a socket that isn't OPEN throws. Guarding with if (socket.readyState === WebSocket.OPEN) is a habit that prevents a class of runtime errors.

javascript
function safeSend(socket, data) {
  if (socket.readyState === WebSocket.OPEN) {
    socket.send(data);
  } else {
    console.warn("socket not open, dropping message");
  }
}
ValueConstantMeaning
0CONNECTINGHandshake in progress
1OPENReady to send and receive
2CLOSINGClose handshake started
3CLOSEDConnection is done

Q12. Can WebSockets send binary data, or only text?

Both. WebSocket frames are typed as text or binary at the protocol level. In the browser you send a string for text, or a Blob or ArrayBuffer for binary; incoming binary arrives as a Blob by default, switchable to ArrayBuffer via binaryType.

Text is usually JSON for app messages. Binary suits media, file chunks, or compact formats like Protocol Buffers where you want fewer bytes on the wire.

javascript
socket.binaryType = "arraybuffer";

socket.onmessage = (event) => {
  if (typeof event.data === "string") {
    handleText(event.data);
  } else {
    handleBinary(new Uint8Array(event.data));
  }
};

Q13. Does WebSocket use TCP or UDP?

TCP. A WebSocket runs on top of a single TCP connection, so it inherits TCP's ordered, reliable delivery: messages arrive in order and aren't silently lost.

That's why WebSocket isn't the right tool for real-time audio or video, where dropping a late packet beats waiting for it; that's WebRTC's job over UDP. WebSocket trades some latency for reliability and ordering.

Q14. What is Socket.IO and how is it different from WebSocket?

WebSocket is the raw protocol. Socket.IO is a library built on top of it that adds features you'd otherwise write yourself: automatic reconnection, rooms and namespaces, acknowledgements, and a fallback to HTTP long polling when WebSocket is unavailable.

The trade-off: Socket.IO isn't plain WebSocket on the wire, so a Socket.IO client needs a Socket.IO server. For simple needs, raw WebSocket is lighter; for chat-style apps that want rooms and resilience out of the box, the library saves work.

Raw WebSocketSocket.IO
What it isBrowser API / protocolLibrary on top
ReconnectionYou build itBuilt in
Rooms / broadcastYou build itBuilt in
Fallback transportNoneHTTP long polling
InteroperableAny WS client/serverNeeds Socket.IO both ends

Key point: Interviewers love 'what does Socket.IO give you over plain WebSocket?'. Reconnection, rooms, and fallback is the crisp three-part answer.

Q15. Why use WebSockets instead of polling?

Polling means the client asks the server for updates on a timer, say every few seconds. Most of those requests come back with nothing new, wasting bandwidth and adding latency equal to the poll interval. WebSocket pushes the update the instant it exists.

Long polling is a middle ground where the server holds the request open until it has data, but it still pays request setup overhead and can't do efficient two-way messaging. WebSocket's one persistent connection beats both for genuinely real-time, bidirectional needs.

Q16. What ports do WebSockets use and why does that help with firewalls?

WebSocket uses the standard web ports: 80 for ws and 443 for wss, the same ports as HTTP and HTTPS. Because the connection begins as an ordinary HTTP request, it passes through most firewalls and proxies that already allow web traffic.

That reuse of port 443 is a practical reason WebSocket won out over older push techniques: you don't need to open a new port, and wss traffic looks like normal HTTPS to the network.

Q17. Does each client keep its own WebSocket connection?

Yes. Every connected client holds one open WebSocket to the server, and the server tracks all of them. To broadcast, the server iterates its set of open connections and sends to each.

This is why WebSocket is stateful and why connection count is the thing you scale. A REST server can handle a request and forget it; a WebSocket server holds thousands of live sockets in memory at once.

javascript
// Node.js with the 'ws' library
import { WebSocketServer } from "ws";
const wss = new WebSocketServer({ port: 8080 });

wss.on("connection", (socket) => {
  socket.on("message", (data) => {
    // broadcast to every connected client
    for (const client of wss.clients) {
      if (client.readyState === 1) client.send(data);
    }
  });
});

Q18. Are WebSocket messages guaranteed to arrive in order?

Yes, within a single connection. Because WebSocket runs on one TCP connection, messages are delivered in the order they were sent and none are silently dropped while the connection is open.

What TCP does not guarantee is that a message reaches the application if the connection drops mid-flight. So ordering is solved for you, but delivery across a reconnection is something your app has to handle, often with message IDs or acknowledgements.

Q19. Do WebSockets follow the same-origin policy and CORS?

WebSockets aren't restricted by the browser's same-origin policy the way fetch is; a page can open a WebSocket to a different origin without a CORS preflight. The handshake does send an Origin header, though.

That's the catch: because the browser won't block cross-origin WebSocket for you, the server must check the Origin header itself and reject connections from origins it doesn't trust. Skipping that check is the cross-site WebSocket hijacking risk.

Key point: Mentioning that the server has to validate Origin because the browser won't is exactly the security awareness this question screens for.

Q20. Can you write a minimal WebSocket echo server?

An echo server accepts a connection, then sends back whatever message it receives. It's the classic first example because it exercises the whole lifecycle: accept, receive, send, in a few lines.

In Node with the ws library you listen for a connection, then for each message on that socket you send the same data back. That loop is the seed of every real WebSocket app; you replace 'echo it back' with actual routing logic.

javascript
import { WebSocketServer } from "ws";

const wss = new WebSocketServer({ port: 8080 });

wss.on("connection", (socket) => {
  socket.on("message", (data) => {
    socket.send(`echo: ${data}`);
  });
});

Key point: Being able to type this from memory is the entry bar. The follow-up is 'now broadcast to all clients instead of echoing', so know wss.clients too.

Back to question list

WebSockets Intermediate Interview Questions

Intermediate21 questions

For candidates with working experience: protocol mechanics, resilience patterns, and the questions that separate users from understanders.

Q21. What is a WebSocket frame and what types exist?

After the handshake, data on the connection travels in frames, not raw bytes. Each frame has a small header with an opcode saying what it is, a length, and (from the client) a masking key, followed by the payload.

Opcodes split into data frames (text 0x1, binary 0x2, continuation 0x0) and control frames (close 0x8, ping 0x9, pong 0xA). Control frames handle the connection itself; data frames carry your messages. A big message can be split across several frames using continuation.

OpcodeFrame typePurpose
0x0ContinuationNext part of a fragmented message
0x1TextUTF-8 text payload
0x2BinaryBinary payload
0x8CloseStart the closing handshake
0x9 / 0xAPing / PongKeepalive control frames

Q22. How do ping and pong frames keep a connection alive?

Ping and pong are control frames used for keepalive. One side sends a ping; the peer must reply with a pong carrying the same payload. This proves the connection is still working end to end and stops idle proxies from closing it.

The server usually pings on a timer. If no pong comes back within a timeout, it treats the connection as dead and cleans it up, which is how you detect half-open connections that TCP alone wouldn't reveal.

javascript
// Node 'ws' server: drop clients that stop responding
setInterval(() => {
  for (const client of wss.clients) {
    if (client.isAlive === false) return client.terminate();
    client.isAlive = false;
    client.ping();
  }
}, 30000);

wss.on("connection", (ws) => {
  ws.isAlive = true;
  ws.on("pong", () => { ws.isAlive = true; });
});

Key point: The insight to state: TCP can go half-open silently, so app-level ping/pong is how you actually know a client is still there.

Q23. How do you handle reconnection when a WebSocket drops?

Connections drop: laptops sleep, networks flap, servers restart. A resilient client listens for the close event and reconnects, but not instantly and not forever at the same interval. You use exponential backoff with jitter so a fleet of clients doesn't reconnect in a thundering herd.

On reconnect, you also re-establish state: re-authenticate, re-subscribe to channels, and often request anything missed while offline using a last-seen message ID. Raw WebSocket gives you none of this, which is one reason libraries exist.

javascript
function connect(url, attempt = 0) {
  const socket = new WebSocket(url);
  socket.onopen = () => { attempt = 0; };
  socket.onclose = () => {
    const base = Math.min(1000 * 2 ** attempt, 30000);
    const delay = base + Math.random() * 1000; // jitter
    setTimeout(() => connect(url, attempt + 1), delay);
  };
  return socket;
}

Key point: Say 'exponential backoff with jitter' explicitly. Reconnecting on a fixed timer is the answer that reveals no production experience.

Q24. How do you detect a dead connection that TCP still thinks is open?

TCP can be half-open: one side is gone but the other's kernel hasn't noticed, so no close event fires. The only reliable fix is an application-level heartbeat. The server pings on an interval and expects a pong; missing pongs mean the client is really gone.

You pair this with a timeout: if two or three heartbeats go unanswered, terminate the socket and free its resources. Without a heartbeat, dead connections pile up and leak memory on a long-running server.

Q25. What is back pressure in WebSockets and how do you handle it?

Back pressure happens when you send data faster than the client (or the network) can accept it. The unsent bytes queue up in a send buffer, and if you ignore it, memory grows until the process is in trouble.

In the browser you watch socket.bufferedAmount and pause sending when it's high. On the server you check the write return value or the buffer size and slow the producer, drop lower-priority messages, or disconnect a client that can't keep up. Ignoring back pressure is a classic cause of a server falling over under load.

javascript
function sendWithBackpressure(socket, data) {
  const LIMIT = 1_000_000; // 1 MB
  if (socket.bufferedAmount > LIMIT) {
    return false; // skip or queue, don't pile on
  }
  socket.send(data);
  return true;
}

Key point: Naming bufferedAmount on the client and 'slow the producer or drop messages' on the server is what separates depth from a textbook definition.

Q26. How do you authenticate a WebSocket connection?

The WebSocket API doesn't let you set custom headers from the browser, so you can't just send an Authorization header. Common patterns: pass a short-lived token as a query parameter on the connect URL, rely on an existing session cookie sent during the handshake, or authenticate with the first message after the socket opens.

Whatever you pick, validate on the server during or right after the handshake and close the connection if it fails. Query-string tokens should be short-lived because URLs land in logs, and cookie-based auth needs CSRF-style protection via the Origin check.

  • Token in the connect URL query string (keep it short-lived)
  • Session cookie sent automatically on the handshake request
  • Auth as the first message, then close on failure
  • Always validate server-side and check the Origin header

Q27. How do you broadcast a message to many clients?

On a single server you keep a collection of open connections and loop over it, sending to each socket that's in the OPEN state. Grouping clients into rooms or channels lets you broadcast to a subset instead of everyone.

The catch appears when you scale past one server: clients are spread across processes, so a plain in-memory loop only reaches the clients on that one server. That's when you move broadcasts through a shared pub/sub layer so every server delivers to its own clients.

javascript
function broadcast(clients, message, exclude) {
  const data = JSON.stringify(message);
  for (const client of clients) {
    if (client !== exclude && client.readyState === 1) {
      client.send(data);
    }
  }
}

Q28. How do you implement rooms or channels?

A room is just a named group of connections. You keep a map from room name to the set of sockets in it; join adds a socket, leave removes it, and a broadcast to a room iterates only that set. Socket.IO ships this, but the idea is a few lines to build.

When you scale to many servers, room membership is spread across processes, so a message published to a room has to fan out through pub/sub to reach members on other servers. The room abstraction stays; the delivery gains a network hop.

javascript
const rooms = new Map(); // roomName -> Set<socket>

function join(room, socket) {
  if (!rooms.has(room)) rooms.set(room, new Set());
  rooms.get(room).add(socket);
}

function toRoom(room, data) {
  for (const s of rooms.get(room) ?? []) {
    if (s.readyState === 1) s.send(data);
  }
}

Q29. How should you structure messages over a WebSocket?

The protocol carries opaque payloads, so you define the shape. Almost every app puts a type or event field on each message plus a data payload, and serializes as JSON. That lets the receiver route each message to the right handler.

For high-volume or bandwidth-sensitive systems, a binary format like Protocol Buffers or MessagePack shrinks the payload and speeds parsing. Whatever the format, versioning the message schema early saves pain when the protocol evolves.

javascript
// a simple typed envelope
socket.send(JSON.stringify({
  type: "chat.message",
  data: { room: "general", text: "hi" },
  id: crypto.randomUUID()
}));

Q30. When would you choose Server-Sent Events over WebSockets?

Choose SSE when you only need server-to-client updates: live feeds, notifications, stock tickers, progress bars. SSE runs over a plain HTTP response, reconnects automatically, and is simpler to deploy because it's just HTTP.

Choose WebSocket when the client also needs to send frequently, like chat or collaborative editing, where the two-way channel matters. SSE is one-directional and text-only, so anything that needs client-to-server messaging or binary frames points to WebSocket.

SSEWebSocket
DirectionServer to client onlyFull-duplex
ProtocolPlain HTTPUpgraded protocol
Auto-reconnectBuilt inYou build it
BinaryText onlyText and binary
Best forFeeds, notificationsChat, collaboration, games

Watch a deeper explanation

Video: How Web Sockets work | Deep Dive (ByteMonk, YouTube)

Q31. How many WebSocket connections can a browser open?

Browsers don't apply the strict per-host limit to WebSockets that they apply to HTTP/1.1 requests; the practical cap is much higher, in the hundreds per host. But you rarely want many: one connection can multiplex all your app's channels using your own message types.

The real limit is on the server: each connection holds memory and a file descriptor, so a single machine tops out in the tens or hundreds of thousands depending on tuning. That server-side ceiling, not the browser, drives your architecture.

Q32. What do proxies and load balancers need to support WebSockets?

The proxy or load balancer has to understand the HTTP Upgrade handshake and then stop treating the connection as a normal request, keeping the TCP connection open and passing frames through. Older or misconfigured proxies buffer or close it, which breaks WebSocket.

You also raise idle timeouts, because a mostly-quiet WebSocket looks idle and a short timeout will kill it (this is partly why heartbeats exist). On layer-7 load balancers you enable WebSocket or Upgrade support explicitly.

Key point: 'raise the idle timeout or the LB kills quiet connections' matters.

Q33. Why might you need sticky sessions with WebSockets?

A WebSocket is one long-lived connection to one server, so once it's established, all its frames go to that server. Sticky sessions (session affinity) make sure the initial handshake and the ongoing connection land on the same backend, which matters if per-connection state lives in that server's memory.

The alternative is to keep no per-connection state on the server and route all shared state through an external store or pub/sub, which removes the need for stickiness but adds a network hop. Which you pick depends on how much you scale out.

Q34. Does WebSocket support message compression?

Yes, through the permessage-deflate extension, negotiated during the handshake. It compresses each message with DEFLATE, which cuts bandwidth for text-heavy payloads like JSON.

It isn't free: compression costs CPU and memory per connection, and with many connections that adds up. For small messages the overhead can outweigh the savings, so you enable it deliberately based on payload size, not by default.

Q35. How do you gracefully shut down a WebSocket server for a deploy?

Stop accepting new connections, then tell existing clients you're going away, commonly with close code 1001 (going away), giving them a chance to reconnect elsewhere. Drain in-flight messages, then close the sockets and exit.

Clients help by reconnecting with backoff, so a rolling deploy spreads reconnections across the fleet instead of a stampede. Without a graceful path, a deploy drops every connection at once and every client reconnects simultaneously.

javascript
function shutdown(wss) {
  wss.close(); // stop new connections
  for (const client of wss.clients) {
    client.close(1001, "server restarting");
  }
}

Q36. Does WebSocket guarantee a message is delivered and processed?

No. TCP guarantees ordered, reliable delivery while the connection is open, but a message in flight when the connection drops can be lost, and there's no built-in acknowledgement that the app processed it.

If you need at-least-once delivery, you build it: give each message an ID, have the receiver acknowledge, and retry unacknowledged messages after a reconnect. Idempotent handlers let you retry safely without double-processing.

Key point: The honest answer, 'the protocol gives ordering, not application-level delivery guarantees, you add acks yourself', indicates real distributed-systems maturity.

Q37. How do you test WebSocket code?

Unit-test your message handlers as plain functions by feeding them parsed messages, so most logic needs no live socket. For the connection layer, spin up a real WebSocket server in the test and a client connects to assert on the open/message/close flow.

For manual checks, tools like wscat on the command line or browser devtools let you open a socket and send frames by hand. The key is separating pure message logic from the transport so the bulk of your tests are fast and don't need a network.

bash
# connect and send a frame by hand
npx wscat -c wss://echo.websocket.org
> hello
< hello

Q38. Why do WebSocket connections sometimes drop after being idle?

Networks in the middle (proxies, load balancers, NAT gateways, mobile carriers) close connections they judge idle to reclaim resources. A WebSocket with no traffic looks idle, so it gets cut even though both ends think it's fine.

The fix is a heartbeat: periodic ping/pong keeps a trickle of traffic flowing so intermediaries don't reap the connection, and it doubles as your dead-connection detector. This is the practical reason nearly every production WebSocket app runs a heartbeat.

Q39. What is a WebSocket subprotocol?

A subprotocol is an application-level protocol name negotiated during the handshake with the Sec-WebSocket-Protocol header. The client offers one or more names, and the server picks one, so both sides agree on the message format before any data flows.

Examples include graphql-ws for GraphQL subscriptions and MQTT over WebSocket. It's a clean way to version or select a message contract at connect time instead of guessing from the payload.

javascript
// client offers subprotocols, server chooses one
const socket = new WebSocket("wss://example.com", ["graphql-ws", "json.v2"]);
socket.onopen = () => console.log("agreed on:", socket.protocol);

Q40. How do you add acknowledgements to WebSocket messages?

WebSocket has no built-in request/response pairing, so you add correlation yourself. Put a unique ID on each message that expects a reply, keep a map of ID to a pending callback or promise, and when a reply arrives carrying the same ID, resolve it. That turns fire-and-forget messaging into ask-and-wait where you need it.

This is the foundation for retries and delivery guarantees: if no ack comes back within a timeout, you resend. Socket.IO ships this pattern as acknowledgement callbacks, but it's a few lines to build on raw WebSocket.

javascript
const pending = new Map();

function request(socket, payload) {
  const id = crypto.randomUUID();
  return new Promise((resolve) => {
    pending.set(id, resolve);
    socket.send(JSON.stringify({ id, payload }));
  });
}

socket.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  if (pending.has(msg.id)) {
    pending.get(msg.id)(msg.result);
    pending.delete(msg.id);
  }
};

Key point: Describing the ID-to-pending-callback map is the answer. It shows you know WebSocket gives you a pipe, not a request/response layer.

Q41. How do you rate limit messages on a WebSocket connection?

A misbehaving or hostile client can flood a connection, so you cap how many messages it may send per window. A token bucket per connection is the common tool: refill tokens over time, spend one per message, and reject or disconnect when the bucket runs dry.

You also cap message size before the payload is buffered, because a giant message is its own denial-of-service vector. Rate limits belong on the server, per connection and often per user, since the client can't be trusted to limit itself.

javascript
function makeLimiter(maxPerSec) {
  let tokens = maxPerSec;
  setInterval(() => { tokens = maxPerSec; }, 1000);
  return () => (tokens > 0 ? (tokens--, true) : false);
}

const allow = makeLimiter(20);
socket.on("message", (data) => {
  if (!allow()) return socket.close(4029, "rate limit");
  handle(data);
});
Back to question list

WebSockets Interview Questions for Experienced Developers

Experienced19 questions

advanced rounds probe protocol internals, scaling design, and production scars. Expect every answer here to draw a follow-up.

Q42. How do you scale WebSockets across many servers?

The core problem: a client connects to exactly one server, so a message that must reach clients on other servers can't be delivered by a local loop. You put a shared pub/sub layer, commonly Redis, between the servers: each server subscribes, and to broadcast, a server publishes so every server delivers to its own connected clients.

Around that you add horizontal scaling behind a load balancer that supports Upgrade, sticky sessions or externalized connection state, per-node connection limits, and heartbeats so dead connections don't leak. Presence (who's online) and message history usually move to their own stores because they can't live in one node's memory.

Broadcasting across a scaled WebSocket cluster

1Client sends
message arrives at the one server it's connected to
2Server publishes
message goes to the shared pub/sub channel (e.g. Redis)
3All servers receive
every server is subscribed to the channel
4Each server fans out
delivers to its own local connected clients

Without the pub/sub hop, a broadcast only reaches clients on the originating server.

Key point: The one sentence that lands: 'a client is pinned to one server, so cross-server delivery needs a shared pub/sub layer'. Everything else follows from that.

Watch a deeper explanation

Video: How to scale WebSockets to millions of connections (Ably Realtime, YouTube)

Q43. What are the main security risks with WebSockets and how do you mitigate them?

The big ones: cross-site WebSocket hijacking (the browser won't enforce same-origin, so the server must validate the Origin header and use unpredictable tokens), unencrypted traffic (always use wss so messages can't be sniffed or tampered with), and missing authorization on every message, not just at connect time.

Add input validation on every inbound message (the connection is a long-lived attack surface), rate limiting and message-size caps to blunt denial-of-service, and short-lived tokens because a WebSocket can outlive a session. Treat each message as untrusted input the same way you'd treat an HTTP body.

  • Validate the Origin header server-side (browser won't do it for you)
  • Use wss:// so traffic is encrypted
  • Authorize per message, not just at connect
  • Cap message size and rate-limit to resist DoS
  • Use short-lived tokens; a socket can outlive a session

Key point: Leading with cross-site WebSocket hijacking and the Origin check is the answer that marks you as someone who's secured a real real-time system.

Q44. How do WebSockets relate to HTTP/2 and HTTP/3?

Classic WebSocket (RFC 6455) upgrades from an HTTP/1.1 request. RFC 8441 defines how to run WebSocket over an HTTP/2 stream using an extended CONNECT, so a WebSocket can share an HTTP/2 connection with other streams instead of monopolizing a whole TCP connection.

HTTP/2 and HTTP/3 also offer their own server-push and streaming primitives, and HTTP/3 runs over QUIC (UDP) to avoid TCP head-of-line blocking. The senior point is that WebSocket isn't the only real-time option anymore, and the right choice depends on your stack and what your proxies support.

Q45. What is a half-open WebSocket connection and why is it dangerous?

A half-open connection is one where one side has gone away (crashed, lost network) but the other side's TCP stack hasn't detected it, so it still believes the connection is live. No close event fires; the socket just sits there.

On a server this is a slow leak: each ghost connection holds memory and a file descriptor, and over time they exhaust resources. The only reliable detection is application heartbeats with a timeout, which is why every serious WebSocket server runs ping/pong and terminates non-responders.

Q46. How do you preserve message ordering across reconnections?

Ordering is guaranteed within one connection by TCP, but a reconnection resets that: messages produced during the gap, or delivered on the new connection, can arrive out of order relative to what the client last saw. You solve it with sequence numbers or a monotonic message ID per stream.

On reconnect the client sends its last-seen ID, and the server replays anything after it in order from a buffer or log. This turns ordering from a transport property into an application property, which is what you need once connections aren't permanent.

Q47. How would you design a presence system (who is online) with WebSockets?

Track presence as connection lifecycle: mark a user online on connect, offline on close, and refresh a TTL on each heartbeat so a crashed client expires instead of showing online forever. Because connections spread across servers, presence state lives in a shared store like Redis, not in one node's memory.

Publish presence changes through pub/sub so interested clients get notified. The subtle parts are debouncing flapping connections (mobile networks reconnect constantly) and handling a user with several devices, where they're online until the last connection drops.

Key point: Naming the TTL-refreshed-by-heartbeat trick and the multi-device edge case is what turns this from a toy answer into a design one.

Q48. Why must client-to-server WebSocket frames be masked?

RFC 6455 requires the client to XOR every frame it sends with a random 32-bit masking key. The reason is a cache-poisoning attack: without masking, a malicious page could craft a WebSocket payload that looks like a valid HTTP request to an intermediary proxy and poison its cache.

Masking makes the client's bytes unpredictable to any proxy on the path, so they can't be mistaken for a crafted HTTP request. Server-to-client frames are not masked, because the client isn't the untrusted party in that direction. A server must reject an unmasked client frame.

Q49. How do you load test a WebSocket service?

You can't just fire independent requests; the load is the number of concurrent open connections plus the message rate on each. Tools like k6, Artillery, or a custom client open tens of thousands of connections, hold them, and drive traffic, while you watch server memory, file descriptors, CPU, and message latency.

The metrics that matter differ from HTTP: connections per node before degradation, memory per connection, broadcast fan-out time, and behavior during a mass reconnection (simulate a deploy). Test the reconnection storm specifically, because that's what actually breaks systems in production.

Q50. How do you build a fallback when WebSockets are blocked?

Some corporate proxies and networks still break WebSocket. A resilient client detects a failed upgrade and falls back to HTTP long polling for two-way messaging or SSE for server-to-client streams, keeping the same application message format so higher layers don't care which transport won.

Libraries like Socket.IO do this automatically by starting on long polling and upgrading to WebSocket when it succeeds. Building it yourself means abstracting the transport behind a small interface so your app logic is transport-agnostic.

Q51. What do you monitor for a production WebSocket system?

Connection-centric metrics, not request-centric: current open connections per node, connect and disconnect rates, close codes (a spike in 1006 abnormal closures signals trouble), message throughput and size, and end-to-end message latency. Memory and file-descriptor usage per node because those are what run out.

Alert on reconnection storms, rising half-open connections, and pub/sub lag if you're scaled out. Logging each connection with an ID lets you trace one client's whole session, which is how you actually debug a flaky real-time bug.

Q52. A WebSocket feature is flaky in production. Walk through your debugging approach.

Observe first: are connections dropping (watch close codes and disconnect rate), stalling (message latency, back pressure, bufferedAmount), or never establishing (handshake failures at the proxy or load balancer)? Correlate with recent deploys and check the usual suspects: idle timeouts too short, a proxy not passing Upgrade, missing heartbeats, or a reconnection storm hammering the servers.

Then reproduce with a raw client (wscat or devtools) to isolate app logic from the network, fix at the right layer, and confirm with the same metric that showed the problem. The structure, observe, hypothesize, verify, fix, confirm, matters more than any single tool.

Key point: the technical evaluation checks the process; naming close code 1006 and idle timeouts is supporting evidence.

Q53. What makes scaling WebSockets harder than scaling REST APIs?

REST is stateless: any server can handle any request, so you scale by adding boxes behind a load balancer. WebSocket is stateful: each connection is pinned to one server for its whole life, so servers hold long-lived state, broadcasts need cross-server coordination, and you can't freely move a live connection.

That statefulness drives everything downstream: sticky sessions or externalized state, pub/sub for fan-out, graceful drain on deploy so you don't drop every connection, and capacity planning by connection count rather than requests per second. It's a different scaling model, not just a bigger one.

REST APIWebSocket
StateStatelessStateful, long-lived
Scaling unitRequests per secondConcurrent connections
Any server?YesNo, pinned to one
BroadcastN/ANeeds pub/sub across servers
DeployRolling, easyMust drain connections

Q54. How do you handle very large messages over a WebSocket?

Don't send them as one frame. WebSocket supports fragmenting a message across continuation frames, and libraries let you set a max message size to reject oversized payloads that could exhaust memory. For genuinely large transfers, chunk the data at the application level and reassemble, or send a reference (a URL) and let the client fetch the blob over HTTP.

The reason to cap size is defensive: an unbounded message is a denial-of-service vector, since the server buffers it before your code sees it. Set a limit, reject beyond it, and stream anything big.

Q55. How do you keep a session alive across a WebSocket reconnection?

The connection is disposable but the session shouldn't be. You give each session a stable ID stored client-side, and on reconnect the client presents it so the server rebinds the new connection to the same logical session: subscriptions, presence, and any buffered messages carry over.

Combine that with a last-seen message ID so the server replays what was missed during the gap. This decouples session identity from the physical connection, which is exactly what lets a mobile client survive network changes without the user noticing.

Q56. What does raw RFC 6455 WebSocket give you, and what do you always end up adding?

RFC 6455 gives you the handshake, framing, full-duplex messaging, and ping/pong control frames. That's the transport. What it deliberately leaves out is everything above: reconnection, acknowledgements and delivery guarantees, rooms and pub/sub, presence, authentication flow, and back-pressure policy.

So real systems either adopt a library (Socket.IO, or managed services) or rebuild these pieces. Knowing the line between what the protocol provides and what your application must own is the distinction this question is checking.

Q57. How do GraphQL subscriptions use WebSockets?

GraphQL subscriptions are the real-time part of GraphQL, and they're usually delivered over WebSocket using a subprotocol like graphql-ws negotiated at connect. The client sends a subscription operation, the server pushes a message every time the subscribed data changes, and either side can complete the subscription.

Underneath, the server ties each subscription to an event source (often the same pub/sub layer you'd use for broadcasting) so a mutation elsewhere triggers the pushed update. It's a structured message contract layered on top of the plain WebSocket transport.

Q58. What drives the memory and CPU cost of a WebSocket server?

Memory scales with concurrent connections: each open socket holds buffers, per-connection state, and a file descriptor, so hundreds of thousands of idle connections still cost real RAM even with no traffic. CPU scales with message rate and any per-message work: JSON parsing, compression, fan-out to many clients.

The design levers are keeping per-connection state small (push shared state to Redis), using an event-driven runtime that handles many connections per thread, being deliberate about permessage-deflate (it trades CPU for bandwidth), and batching or throttling broadcasts so a hot room doesn't saturate a core.

Key point: The framing the technical value is: 'memory tracks connection count, CPU tracks message rate'. It shows you know which knob to turn for which bottleneck.

Q59. How does Redis pub/sub fan a broadcast out across WebSocket servers?

Each WebSocket server subscribes to a Redis channel on startup and keeps its own local clients in memory. To broadcast, a server publishes the message to the channel instead of looping only its own clients. Redis delivers that message to every subscribed server, and each server then sends it to its own connected clients.

So the fan-out is two-level: Redis fans out to servers, servers fan out to clients. The trade-off is an extra network hop and Redis as a dependency, but it's what lets a message from a client on server A reach a client on server B.

javascript
import { createClient } from "redis";
const sub = createClient();
const pub = createClient();

await sub.subscribe("broadcast", (message) => {
  for (const client of wss.clients) {
    if (client.readyState === 1) client.send(message);
  }
});

// to broadcast from any server:
function broadcast(data) { pub.publish("broadcast", data); }

Key point: The clean summary: 'Redis fans out to servers, each server fans out to its own clients'. Two levels, one dependency.

Q60. How do you resume a session and replay missed messages after a reconnect?

Give each stream a monotonically increasing sequence number and have the server keep a short buffer or log of recent messages. The client remembers the last sequence it saw. On reconnect it sends that number, and the server replays everything after it in order before resuming live delivery.

This bridges the gap where a client was disconnected. It works with an idempotent client so a replayed message it already applied does no harm, and the buffer has a bound so it can't grow forever, at which point a client that's too far behind does a full resync instead.

javascript
// client resumes from its last-seen sequence
function resume(socket, lastSeq) {
  socket.send(JSON.stringify({ type: "resume", lastSeq }));
}

// server replays the tail of its buffer, then goes live
function onResume(socket, lastSeq, buffer) {
  for (const msg of buffer.filter((m) => m.seq > lastSeq)) {
    socket.send(JSON.stringify(msg));
  }
}

Key point: Naming the last-seen sequence plus a bounded server buffer, with a full resync fallback, is the answer that indicates real production experience.

Back to question list

WebSockets vs HTTP Polling, SSE, and WebRTC

WebSocket wins when you need low-latency, two-way messaging over one connection: chat, live dashboards, collaborative editing, multiplayer games. It trades the simplicity and caching of stateless HTTP for a persistent, stateful connection you have to keep alive and scale. Where it loses is one-directional server-to-client streaming, where Server-Sent Events are simpler and auto-reconnect for free, and peer-to-peer media, where WebRTC fits better. Knowing these trade-offs out loud is itself an interview signal: it shows you pick transports on merits, not habit.

TransportDirectionRuns overBest at
WebSocketFull-duplex (both ways)One TCP connectionChat, live collaboration, games
HTTP long pollingClient asks, server repliesRepeated HTTP requestsFallback where WebSocket is blocked
Server-Sent EventsServer to client onlyOne HTTP response streamLive feeds, notifications, tickers
WebRTCPeer to peerUDP (usually), data channelsAudio, video, direct P2P data

How to Prepare for a WebSockets Interview

Prepare in layers, and practice out loud. Most WebSocket rounds move from protocol concepts to a live coding task to a scaling or debugging discussion, so rehearse each stage rather than only reading answers.

  • Master your tier's concepts until you can explain the handshake and the ws/wss difference without notes, then read one tier up.
  • Type and run every snippet; wiring up a tiny client and server cements the API far faster than reading.
  • Practice thinking aloud on a small design (a chat room, a live counter) with a timer, because your process is the technical point.
  • Take the quiz on this page to find weak spots, then revisit those questions before the real round.

The typical WebSockets interview flow

1Concept screen
what a WebSocket is, handshake, ws vs wss, vs HTTP
2API and code
open a connection, send/receive, handle close and error events
3Live build
a small real-time feature like a chat or live counter
4Scaling and debugging
keepalive, reconnection, load balancing, back pressure

Earlier rounds increasingly run as AI coding interviews. The concepts on this page are what gets probed at every stage.

Test Yourself: WebSockets Quiz

Ready to test your WebSockets knowledge?

10 questions, about 6 minutes. Score 70% or higher to earn a shareable certificate.

10 questions Instant feedback Free certificate on 70%+

Frequently  Asked  Questions

Which WebSockets topics should I prioritize before a technical round?

Prioritize the areas that change real decisions: fundamentals, practical tasks, debugging, trade-offs, and evidence. The highest-value questions are tied to a project example, a validation check, or a failure mode.

Are these questions enough to pass a WebSockets interview?

They cover the question-answer portion well, but most rounds also include live coding: wiring a small real-time feature while explaining your thinking. building a tiny chat or live counter out loud with a timer is the practice path. Our AI coding interview prep guide covers that format, including how automated evaluation reads your process.

Do I need to know a specific library like Socket.IO?

Know the raw protocol first: the browser WebSocket API, the handshake, and the ws/wss schemes. Libraries like Socket.IO add reconnection, rooms, and fallbacks on top, and interviewers often ask what they give you over plain WebSocket. If a role names a stack, learn its client, but answer protocol questions in terms of the standard.

How long does it take to prepare for a WebSockets interview?

If you've built real-time features before, a few days of an hour a day covers this bank with practice runs. Starting colder, plan a week or two and write a working client and server yourself; reading answers without wiring up a socket is how preparation quietly fails.

Do interviewers ask exactly these questions?

The concepts repeat far more reliably than the exact wording. Interviewers rephrase, chain follow-ups, and push toward whatever you claim confidence in. Prepare the underlying ideas: the handshake, full-duplex framing, keepalive, reconnection, and scaling, and the phrasing takes care of itself.

Is there a way to test my WebSockets knowledge?

Yes. The quiz on this page scores you as you go and explains every answer, so you find your weak spots fast. Pass the threshold and you can download a shareable certificate with your name and score, free and with no sign-up. It's the quickest way to check yourself before the real round.

From the team that builds coding interviews

Hyring builds the AI Coding Interviewer that runs live technical rounds in 20+ languages for 5,000+ hiring teams. These WebSockets questions and scoring notes reflect what actually gets asked and evaluated inside the interviews we host.

See how the AI Coding Interviewer works

Sources

Adithyan RKWritten by Adithyan RK
Surya N
Fact-checked by Surya N
Published on: 13 Jun 2026Last updated: 29 Jun 2026
Share: