The Runtime Theory
mediumApplicationDSA#networking#http#realtime#websockets

Explain the cost difference between polling, SSE, and websockets

Probes whether you price these three by what the machine actually does — per-request overhead, connection state, and the direction of data flow — not by buzzwords.

The Runtime Theory Team2 min readasked at meta · stripe · spotify · uber

This question is really "price the three options per message." A strong answer doesn't say "websockets are better" — it counts bytes and round trips and connection state, because each option's cost profile is what decides the right fit.

Polling. The client asks "anything new?" on a schedule — every 5s, say. Each poll is a full HTTP request: connection setup if not reused, headers (~500 bytes each way), server work, response. On a reused keep-alive connection, each poll is still a server round trip: at 100ms RTT, you burn 1.2s of client-server time per minute just in polls, whether or not data exists. Fixed cost per interval, zero marginal cost per message, and messages arrive up to one interval late. Cost scales with interval, not traffic.

Long polling is the tuned variant: the request hangs open until data arrives (or a 30-60s timeout), so the per-message latency drops to a round trip while the per-interval cost drops to near-zero when idle. But each delivery is still a fresh request: at high message rates it degenerates into HTTP request churn — one request/response pair per message, with headers and new server work each time.

SSE. One long-lived HTTP connection the server writes to. The cost structure: one connection setup (TCP + TLS, 2-3 RTTs on cold start), then zero overhead per message beyond the frame itself — the connection amortizes everything. Server holds one open socket per client; clients can't send (SSE is one-directional, so a client message is another request). It rides on regular HTTP, so it inherits proxies, compression, and reconnection via Last-Event-ID. Cost is per-connection-kept-open, tiny per-message, and it survives NAT/HTTP middleboxes because it looks like a long-lived GET.

Websockets. A persistent bidirectional connection: one handshake (HTTP Upgrade), then both directions flow as raw frames (2 bytes of overhead per frame vs ~500+ bytes of HTTP headers). The real costs: the server holds a socket, a TCP buffer, and per-connection state (memory, timers, and with TLS, a session) regardless of activity — a 10k idle websocket connection count is normal, 100k starts to cost real RAM and fd pressure. And it abandons HTTP semantics: no caching, no proxies that understand it, no HTTP/2 multiplexing — each socket is a dedicated TCP connection, so N sockets = N connections, unlike HTTP/2's stream sharing.

The tradeoff chart: polling = fixed cost by interval, high latency; SSE = near-zero per-message cost, one-directional, server-friendly; websockets = bidirectional, cheapest per message in both directions, most expensive per idle connection. Choose SSE unless the client must push — that single rule covers most designs.

This answer walks

Follow-ups they'll push on

  1. 01When would you actually choose polling over SSE?
  2. 02What does a websocket connection cost the server to hold idle?
  3. 03Why is SSE one-directional and how does that show up in cost?

More interviews in this topic

One dispatch a week

The trace behind each question, the tradeoff that explains it, and one technical dispatch per week — no noise.

One technical dispatch per week. No noise.