The web was built on a simple idea: your browser asks for something, the server answers, and the conversation ends. That request-response model powered the web for decades — but it can’t easily do real-time. When you need a live chat, a collaborative document, a stock ticker, or a multiplayer game, you need WebSockets. Here’s what they are and why they changed what the web can do.
The problem with plain HTTP for real-time
Regular HTTP is one-directional and short-lived: the client asks, the server responds, and the connection closes. The server has no way to speak up on its own. So how did early “live” web apps work? With hacks. Developers used polling — having the browser ask “any updates?” every few seconds — or long-polling, holding a request open until something happened. Both work, but they’re wasteful: constant new connections, wasted requests that return nothing, and noticeable lag.
What these apps really needed was a single, persistent, two-way connection where either side could send data the instant it had something to say. That’s exactly what WebSockets provide.
What a WebSocket is
A WebSocket is a persistent, full-duplex communication channel over a single TCP connection. “Full-duplex” means both the client and the server can send messages at any time, independently — like a phone call, where either person can talk whenever, versus HTTP’s walkie-talkie “your turn, my turn” style.
Once the connection is open, it stays open. There’s no re-establishing a connection for every message, no repeated HTTP headers, and no polling. When the server has news, it pushes it to the client immediately. When the client has input, it sends it straight down the same pipe.
How a WebSocket connection begins: the handshake
WebSockets start life as a normal HTTP request. The browser sends a request with a special Upgrade: websocket header, essentially asking the server to switch protocols. If the server agrees, it responds with a 101 Switching Protocols status, and from that moment the connection is “upgraded” from HTTP to the WebSocket protocol.
This handshake design is deliberate and clever: because it begins as HTTP, WebSockets work over the same ports (80 and 443) and pass through most existing web infrastructure. The secure version uses wss:// (WebSocket Secure), the encrypted equivalent of https://.
What they’re great for
WebSockets are the right tool whenever low-latency, two-way communication matters:
- Chat and messaging — messages appear instantly for everyone.
- Collaborative editing — think multiple cursors moving in a shared document.
- Live dashboards and tickers — prices, metrics, and scores that update the moment they change.
- Multiplayer games — where every millisecond of latency counts.
- Notifications — pushing alerts to users without them refreshing.
When you probably don’t need them
WebSockets are powerful, but they’re not a default. A persistent connection consumes server resources for every connected client, and it adds complexity: you have to handle reconnection when a connection drops, scale connections across multiple servers, and manage state. If your app just fetches data occasionally, plain HTTP requests are simpler and perfectly fine. And if you only need the server to push to the client (one-directional), Server-Sent Events (SSE) are a lighter option worth considering.
WebSockets in practice
In the browser, the API is refreshingly simple — you create a connection and react to events for when it opens, when a message arrives, and when it closes. On the server side, you’ll typically reach for a library (like Socket.IO in the Node world) that handles the tricky parts: reconnection, fallbacks for hostile networks, and broadcasting messages to groups of clients. These libraries smooth over the rough edges so you can focus on your app’s logic rather than protocol plumbing.
A minimal WebSocket example
Here’s how little code a browser needs to open a live channel:
const socket = new WebSocket('wss://example.com/live');
socket.addEventListener('open', () => {
socket.send(JSON.stringify({ type: 'subscribe', channel: 'prices' }));
});
socket.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
console.log('Update:', data);
});
socket.addEventListener('close', () => {
// reconnect logic goes here
});
Three event handlers and you have real-time updates. Notice the message format: WebSockets deliver raw text or binary, so most apps define their own small JSON protocol on top — a type field and a payload. That’s worth designing deliberately early, because every feature you add will speak it.
The production concerns nobody mentions in tutorials
Getting a WebSocket demo running takes ten minutes. Running WebSockets in production is where the real engineering lives, and three problems dominate.
Reconnection. Connections drop constantly in the real world — phones switch networks, laptops sleep, proxies time out idle connections. Your client must detect drops and reconnect automatically, ideally with exponential backoff so a struggling server isn’t hammered by thousands of clients retrying every second. You’ll also want heartbeats (periodic ping/pong messages) to detect “zombie” connections that look open but are dead.
Scaling beyond one server. HTTP requests can go to any server behind a load balancer, but a WebSocket is pinned to the machine it connected to. The moment you run two servers, a message published on server A must somehow reach a user connected to server B. The standard fix is a pub/sub backbone — often Redis — that relays events between servers. Plan for this before you need it.
State and missed messages. What happens to messages sent while a client was briefly disconnected? If the answer matters for your app (it usually does for chat), you need sequence numbers or a “fetch what I missed” API on reconnect. Real-time transport and reliable delivery are separate problems.
Frequently asked questions
Do WebSockets work through firewalls and proxies? Generally yes — that’s the payoff of the HTTP handshake design. Using wss:// (the encrypted variant) makes traversal even more reliable, since intermediaries can’t inspect and interfere with the traffic. Use wss:// always, for security and compatibility alike.
How many WebSocket connections can a server handle? More than you’d guess — a well-tuned server can hold tens of thousands of mostly-idle connections, since each costs memory rather than CPU. The practical limit depends on message volume: 10,000 quiet connections are cheap; 10,000 chatty ones are not.
WebSockets or Server-Sent Events? If data flows only server-to-client — live scores, notifications, a activity feed — SSE is simpler: it’s plain HTTP, auto-reconnects natively, and needs no special server support. Choose WebSockets when the client also needs to push data back over the same channel, as in chat, games, and collaborative editing.
The takeaway
WebSockets unlock true real-time on the web by replacing HTTP’s one-shot request-response with a single, persistent, two-way connection. They start as an HTTP handshake, upgrade to a live channel, and let both sides send data the instant they have it — no polling, no lag. Reach for them when you need genuine real-time interaction like chat, collaboration, or live data, and stick with simple HTTP when you don’t. Used in the right place, they make experiences possible that the classic web simply couldn’t deliver.

