Skip to main content
WebSocketlesson 4 of 4 · 2 min read

When Not to Use It

Make it earn its way in

Reach for boring HTTP first and make WebSocket earn its way in.

Rule it out immediately for request-and-response work: fetching a profile, submitting a form, listing orders. Plain HTTP hands you caching, retries, safe repeats, CDN offload, status codes, and every debugging tool ever written.

Tunnel those calls through a socket and you forfeit all of it to save header bytes that HTTP/2 was already compressing.

Check your platform second. Serverless stacks treat a long-lived connection as a foreign object, billing per connection-minute and per message, with a routing model that surprises everyone the first time. CDNs cannot cache socket traffic.

Expect every hop in your path to acquire an opinion about connections that live for hours, from balancer timeouts to proxy settings to how long a pod is allowed to take shutting down.

What your clients are actually doing

Check your clients third, because they cut the same way. Phones hop between towers and wifi constantly, so a mobile socket feature is really a reconnect-and-resume state machine with a socket attached. Holding the radio warm for a channel delivering three events a day shows up in somebody's battery report.

Test it on frequency, which is the honest measure. Events spaced minutes or hours apart belong on polling or on server-sent events. Only sustained high rates or genuinely two-way traffic, shared editing, gameplay, market data with orders going back, pays for a fleet.

Take none of this as a case against WebSocket, only against defaulting to it. The products that run sockets do it because their work is socket-shaped: constant, two-way, latency-sensitive. A notifications bell is none of those, and the cheaper tools earlier in this course deliver it with a fraction of the moving parts.

the shape of it
Server push?Plain HTTPREST, cache, retryWhich direction?SSEserver to clientWebSocketfull duplexnoyesdown onlyboth, frequent
step 1 of 2
WebSocket is the last stop on the decision path, not the first.

Worked example

A B2B analytics startup ships in-app notifications over WebSocket because a competitor's job posting mentioned it. Average delivery: 4 notifications per user per day. Over two quarters the connection layer generates 11 production incidents: idle timeout mismatches after an Nginx upgrade, a reconnect loop that DDoSed their own auth service from mobile clients, phantom connections inflating memory. Meanwhile the actual requirement, a bell icon that updates within a minute, never needed any of it. Fatima replaces the whole layer with a 45 second poll against a cached endpoint during a hack week, deletes about 3,000 lines including the reconnect state machine, and the feature's incident count goes to zero. The postmortem's summary line: we built for the message rate we wished we had.

WebSocket: wrapping up

In the real world

  • 01WhatsApp ran over 2 million concurrent connections on a single Erlang/FreeBSD server in 2012, still the reference number for how far one tuned box can go.
  • 02Slack clients hold a WebSocket to edge servers for messaging, and the company built Flannel, an edge cache, specifically to survive the reconnect storms that follow network blips.
  • 03Discord's gateway runs on Elixir and holds millions of concurrent WebSocket connections, using streaming zlib compression to cut gateway bandwidth by roughly 40 percent.
  • 04Figma's multiplayer editing flows over WebSocket to a sync server that owns each document, a service the team rewrote in Rust when the original Node version hit scaling limits.
  • 05Coinbase and Binance publish market data over public WebSocket feeds, where per-message overhead matters because bursts reach thousands of ticks per second.

Questions people ask

How do I authenticate a WebSocket from a browser if I cannot set headers?

The browser constructor only takes a URL, so the usual options are a session cookie, a short-lived token in the query string, or a first-message auth exchange right after connecting. Cookies flow automatically but WebSocket ignores CORS, so verify the Origin header server-side to block cross-site connections. Whichever you choose, decide how to evict a connection whose session gets revoked hours after the handshake.

How many WebSocket connections can one server handle?

Tens to hundreds of thousands on a tuned box, budgeting a few tens of kilobytes of memory per idle connection, with WhatsApp's 2 million per server as the famous upper bound. The defaults get in the way long before the hardware does: file descriptor limits, framework connection caps, and load balancer ceilings. In practice the binding constraint is usually fan-out and deploy handling, not raw connection count.

Should I use WebSocket or SSE for my feature?

Count the messages the client sends. If the answer is rarely or never, SSE plus ordinary POSTs is less code, easier infrastructure, and comes with built-in reconnection. WebSocket earns its keep when the client sends frequently, needs binary frames, or the feature needs sustained sub-100 ms bidirectional traffic like collaborative cursors or gameplay.

Quick review

Handshake:
client sends HTTP GET with Upgrade: websocket header. Server responds 101 Switching Protocols
After upgrade:
binary framing protocol over same TCP connection. Much lower overhead than HTTP per message
Full-duplex:
server AND client can send messages independently at any time. No request-response cycle
Horizontal scaling:
WebSocket is stateful. User connected to server A can't receive message from server B. Fix: pub/sub relay (Redis) between servers
Load balancing:
needs sticky sessions (IP hash) or shared message bus so all server instances can reach all users
Heartbeat (ping/pong):
send ping frames every 30s to detect dead connections and keep through idle-killing proxies
Capacity:
a tuned server holds tens of thousands of concurrent connections; WhatsApp famously ran ~2M per box on Erlang. Budget ~10 KB kernel + app memory per idle connection
Use cases:
chat (WhatsApp, Slack), collaborative editing (Google Docs), multiplayer gaming, live trading, real-time dashboards
the trade-off

Stateful connections make horizontal scaling harder. Long-lived connections need careful resource management.

in the room

Any bidirectional real-time communication where both client and server need to send unprompted messages.