WebSockets vs Server-Sent Events vs Long Polling

WebSockets vs SSE vs long polling: how each pushes data to clients, connection costs at scale, and how chat and live feeds use them.

Intermediate 3 min read · Updated

Plain HTTP is request-response: the client asks, the server answers. Chat, live scores, notifications, collaborative editing and dashboards need the server to push data as soon as something happens. The three main techniques are long polling, server-sent events (SSE) and WebSockets.

Short polling (the baseline)

The client asks "anything new?" every few seconds. Simple, but wasteful: most responses are empty, and an update waits for the next poll, so latency is up to the full interval. Fine for data that changes rarely; poor for chat.

Long polling

The client sends a request and the server holds it open until there is new data (or a timeout of, say, 30 seconds), then responds. The client immediately sends the next request.

ClientServerGET /updates?after=41server holds the request…200 [message 42]GET /updates?after=42nothing for 30 s204 (timeout, reconnect)
Long polling: the server parks each request until something happens, so updates arrive almost immediately without constant empty responses.
  • Pros: works everywhere plain HTTP works, including old proxies; easy to add to a REST API.
  • Cons: a new request per message adds headers and overhead; held requests tie up server resources; ordering and missed messages need a cursor (after=42).

Server-sent events (SSE)

SSE is a standard for streaming text events from server to client over one long-lived HTTP response (Content-Type: text/event-stream). Browsers support it natively through EventSource, which reconnects automatically and resumes with the Last-Event-ID header.

id: 43
event: score
data: {"match": "IND-AUS", "runs": 287, "wickets": 6}

id: 44
event: score
data: {"match": "IND-AUS", "runs": 291, "wickets": 6}
  • Pros: plain HTTP (works with HTTP/2 multiplexing, proxies and load balancers), automatic reconnection and resumption, very simple.
  • Cons: one direction only (client-to-server still uses normal requests) and text only.

WebSockets

A WebSocket starts as an HTTP request with Upgrade: websocket, then becomes a persistent, full-duplex connection carrying small framed messages both ways with very low overhead.

  • Pros: true bidirectional, low-latency messaging, text or binary, minimal per-message overhead. The natural fit for chat, multiplayer games and collaborative editing.
  • Cons: you handle reconnection, heartbeats and resumption yourself; some proxies and corporate networks interfere; long-lived stateful connections complicate load balancing and deploys.

Comparison

Long pollingSSEWebSockets
DirectionServer → client (per request)Server → clientBoth ways
ConnectionRepeated HTTP requestsOne long HTTP responseOne upgraded TCP connection
LatencyLow, plus a reconnect per messageLowLowest
ReconnectionBuilt into the loopAutomatic (EventSource)Your code
Overhead per messageHigh (full HTTP request)LowVery low
Best forSimple, infrequent updates; legacy environmentsFeeds, notifications, live scores, AI token streamingChat, games, collaboration, trading

Scaling persistent connections

Holding millions of connections changes the architecture. Connections are cheap individually (tens of KB of memory each with a tuned server) but they are stateful: a message for user B must reach the specific server holding B's connection.

send to Bwhere is B?to gateway 2User AUser BWS gateway 1WS gateway 2Chat servicePresence registryuser → gatewayPub/subper-gateway channel
Gateways hold connections and register who is connected where; a pub/sub layer routes each message to the gateway holding the recipient.
  • Separate connection gateways from business logic so you can deploy logic without dropping connections.
  • Track presence: which gateway holds each user, with a TTL refreshed by heartbeats.
  • Use pub/sub (Redis, Kafka, NATS) to deliver to the right gateway.
  • Load balance with least connections, and on deploys drain gracefully: tell clients to reconnect elsewhere, with jittered backoff to avoid a reconnection storm.
  • Persist messages first, push second, so a client that missed pushes can catch up with a cursor when it reconnects.

Where it’s used

WhatsApp, Slack and Discord

Keep a persistent WebSocket (or similar) per client, with gateway fleets holding millions of connections and pub/sub fan-out behind them.

ChatGPT and LLM APIs

Stream generated tokens to the browser with server-sent events, since the stream is one-way and HTTP-friendly.

Stock tickers and sports scores

Push price and score updates over SSE or WebSockets to many read-only subscribers.

Figma and Google Docs

Use persistent bidirectional connections to exchange edits and cursor positions in real time.

In an interview

  • Pick the simplest technique that fits: SSE for one-way feeds, WebSockets for two-way chat or games, long polling only for constraints like old proxies.
  • Explain how a message finds the recipient's connection: presence registry plus pub/sub between gateways.
  • Persist before pushing, and let reconnecting clients catch up from a cursor or last event ID.
  • Address connection limits per server, heartbeats, and graceful draining on deploys.