A WebSocket is a persistent, full-duplex connection between client and server that allows either side to push messages at any time, in contrast to HTTP request and response where the server can only reply to a request the client made.
In simpler words
WebSockets let the server tell the browser something happened right away, instead of the browser having to keep asking.
The judgment call: which features actually need a live push channel versus which just need a refetch or a short poll.
Explain the difference between polling and WebSockets
Name a tickets feature that justifies real-time push
Describe how auth works on a socket connection, since it is not automatic
Reason about horizontal scaling of stateful socket servers
When a live channel is worth the complexity
Definition
A feature benefits from WebSockets when the cost of a user not seeing an update immediately is high and the update frequency is unpredictable, unlike periodic polling which is acceptable when staleness of a few seconds is fine.
In simpler words
Use a live socket for moments that must show instantly. Use ordinary polling or refetch-on-focus for everything else.
Good candidates: a live typing indicator, a shared ticket board where teammates see status changes without refreshing, or a notification badge that must update the moment something happens.
Bad candidates: a settings page, a report only viewed occasionally, or anything where refreshing a cached query every thirty seconds or on window focus is indistinguishable to the user.
TanStack Query features such as refetch on window focus and stale time often solve keeping data fresh without any socket infrastructure at all. Reach for WebSockets only when push semantics change the experience meaningfully.
A pushed event updates the same query cache a normal fetch would populate. Only the transport changes, not the ownership of state.
Auth and scaling are not automatic
Definition
A WebSocket handshake must carry the same authentication credential, such as an httpOnly cookie, that the HTTP API uses, and because a socket server holds open per-connection state, routing all of one client messages to the same server instance requires sticky sessions or a shared pub-sub backbone across instances.
In simpler words
A socket connection needs to prove who the user is just like an HTTP request does, and running more than one server instance requires a way to share who is connected where.
Do not assume a socket connection is authenticated just because the earlier HTTP login succeeded. The handshake must present the same cookie or token, and the guard equivalent runs on connect.
A single Nest instance can hold all active sockets in memory. Two or more instances behind a load balancer need either sticky sessions, so the same client always reaches the same instance, or a shared broadcaster, such as Redis pub-sub, so an event published on one instance reaches a socket connected to another.
This is the same lesson as caching and queues: a stateful in-memory feature that works on one instance can silently break the moment it scales horizontally.
Keep in mind
Prefer query refetch or polling until a feature genuinely needs sub-second push.
Authenticate the socket handshake explicitly; never assume it inherits HTTP auth for free.
Plan for more than one server instance before relying on in-memory socket state.
Test
Check your understanding
At least 10 questions — mix of concept, syntax, practical, and logic. Score ≥ 80% (enforced by the API) to save progress.