EXPLAINER

WebSockets

WebSockets are a persistent two-way connection between a client and a server, used for live updates. They are more machinery than HTTP request and response. Many AI chat UIs only need server-sent events, not a full socket.

Short answer: A WebSocket is a long-lived two-way connection. Use it for truly interactive streams (collaboration, games, live dashboards). For one-way model tokens, server-sent events are often simpler than a socket. See Streaming AI Responses for Chat UIs.

What it is

A WebSocket starts as an HTTP request that asks to upgrade the connection. If the server agrees, the same TCP connection stays open and both sides can send messages at any time. Messages are frames of text or bytes, not HTTP requests with status codes. The URL scheme is ws or wss (the TLS version, which you want anywhere real).

This is different from a normal REST call, which opens, responds and finishes. It is also different from server-sent events (SSE), which is a one-way stream from server to browser over ordinary HTTP. Streaming AI Responses for Chat UIs is usually that one-way pattern: the model produces tokens, the user does not send a second stream on the same socket.

Why and when it is used

Use WebSockets when both sides must push without waiting for the other to ask: a collaborative editor, a multiplayer position update, a trading screen, a chat where typing indicators and new messages arrive while the user is also sending. Use SSE or chunked HTTP when the server is streaming a response to one request, which covers most "token streaming" AI UIs. Use polling when updates are rare and you want the simplest operations story.

Do not open a WebSocket because a tutorial did. A socket is a long-lived resource. It needs heartbeats, reconnects, authentication that survives reconnect, and a plan for what happens when you run two server instances.

How it works

The browser calls new WebSocket(url). The server accepts the upgrade and keeps the socket in memory, often in a map from user id to connection. Messages you define are application protocol: JSON text such as { "type": "join", "room": "1" }. The server must validate them. There is no framework-level schema unless you add one. If the network drops, the browser does not magically resume; you write reconnect and you decide which messages were missed (a sequence number, or a refresh from HTTP).

Load balancers must allow upgraded connections and idle timeouts longer than your heartbeat interval. Sticky sessions or a shared pub/sub (one socket server publishes, all instances subscribe) are how a message reaches a user who is connected to a different instance. Without that, user A on server 1 will not hear user B on server 2.

Technologies and dependencies

A server that can hold many open connections (Node is comfortable here; so are Go and others), TLS termination that understands upgrades, and an auth scheme. Cookies on the upgrade request are common. A token in the query string leaks into logs; prefer cookies or a short-lived ticket. Frontend and Backend still applies. GraphQL has a subscription transport that may use WebSockets; you do not need GraphQL to use sockets.

How to get started

  1. Decide whether you truly need two-way push. If the server only streams one response, implement SSE first.
  2. If you still need sockets, add a wss endpoint that accepts a connection, sends one hello message, and echoes a ping.
  3. Authenticate the upgrade. Reject missing users before you store the socket.
  4. Define three message types and ignore unknown ones safely.
  5. Kill the network in devtools and implement reconnect with backoff.
  6. Run two server processes and see a message fail to cross. Then add a pub/sub or accept a single instance explicitly.

Write the application protocol down. A socket without a schema becomes an undocumented mess within a month.

Cautions and trade-offs

Open connections consume memory. A million idle sockets is an architecture, not a default. Heartbeats that are too slow look like hangs; too fast waste batteries. Browsers limit sockets per host.

Security: a WebSocket is a cross-site channel. Check Origin on the upgrade. Do not trust a user id inside the first message without a credential. Broadcast bugs leak one tenant's events to another. And reconnect storms after a deploy can take the API down if every client retries at the same second. Jitter the backoff. Finally, do not push secrets or full documents over the socket when a notification ("document changed") and a normal HTTP fetch would do.