SD System Design In Depth
0%
lesson system-designrealtimetransport

WebSockets vs SSE vs long polling

Module 4.4: Real-Time Messaging & Feed Architectures Updated Sep 18, 2026
📄 Cheat Sheet
Long Polling, Websockets, Server Sent Events - Who Wins? | Systems Design  with Ex-Google SWE
Jordan has no life Long Polling, Websockets, Server Sent Events - Who Wins? | Systems Design with Ex-Google SWE Watch on YouTube ↗

Directly compares all three transports with the system-design trade-offs (connection cost, direction, load balancing) rather than just API syntax.

0:00 / --:--

Comparing Real-Time Protocols

When designing a real-time feature, you have three primary architectural choices for pushing data to the client. Choosing the wrong one can lead to massive network overhead or battery drain.

Short & Long Polling

Short Polling: The client asks the server every X seconds if there is new data. This is simple but highly inefficient. Most requests return empty, wasting server CPU and mobile battery.

Long Polling: The client makes a request, but the server holds the connection open until new data is available or a timeout occurs. Once the client gets data, it immediately opens a new long-polling request. It works over standard HTTP, bypassing corporate firewalls easily, but it still incurs the overhead of HTTP headers on every new request (keep-alive usually reuses the underlying TCP connection).

Server-Sent Events (SSE)

SSE is a unidirectional protocol over HTTP. The client establishes a connection, and the server continuously streams data down to the client. The client cannot send data back over this same channel (it must make separate POST requests). The browser's EventSource reconnects automatically and sends Last-Event-ID so the server can resume; over HTTP/1.1 each stream uses one of the browser's roughly six connections per origin, a limit HTTP/2 multiplexing removes.

Best for: Real-time feeds, stock tickers, or live sports scores where data flows only from Server to Client.

WebSockets

WebSockets upgrade a standard HTTP connection into a fully bidirectional, persistent TCP connection. Both client and server can send data asynchronously with minimal overhead (no heavy HTTP headers).

Best for: Multiplayer games, collaborative editing (Google Docs), and low-latency chat applications.

Protocol Direction Use Case
Long Polling Emulated server-to-client push; client-to-server uses ordinary requests Legacy support, strict firewalls
SSE Server to Client only Live feeds, notifications
WebSockets Bi-directional Chat, gaming, real-time collab

Worked example: one million clients, one update per minute

Suppose 1,000,000 connected clients, each receiving on average one update every 60 seconds.

  • Short polling every 5 s: 200,000 requests per second. Only about 1 in 12 polls returns data, so roughly 92 percent of the work is wasted. At around 800 bytes of request plus response headers, that is about 160 MB/s (1.3 Gbit/s) of header traffic alone.
  • Long polling with a 30 s timeout: each client re-issues a request after every update or timeout. With updates arriving randomly every 60 s on average, the expected wait per request is about 60 x (1 - e^-0.5), roughly 23.6 s, so about 42,000 requests per second. Much better, but each response still pays full HTTP headers and a reconnect.
  • SSE or WebSocket: 1,000,000 idle connections held open and about 16,700 messages per second pushed, each with only a few bytes of framing (WebSocket frame headers are 2 to 14 bytes). The cost moves from CPU and bandwidth to memory and connection management.

Detailed comparison

PropertyLong pollingSSEWebSocket
DirectionServer to client push emulated; client sends via normal requestsServer to client onlyFull duplex
TransportPlain HTTP request per message batchOne long HTTP response (text/event-stream)HTTP upgrade to the WebSocket protocol
Reconnect and resumeManualBuilt into EventSource with Last-Event-IDManual; you design session resume
PayloadAnything HTTP carriesUTF-8 text onlyText or binary frames
Proxy and CDN friendlinessExcellentGood; buffering proxies must be configured not to bufferNeeds upgrade support and long idle timeouts
Typical useFallback, very constrained networksNotifications, dashboards, LLM token streamingChat, multiplayer games, collaborative editing

How real systems choose

  • LLM APIs such as OpenAI's and Anthropic's stream tokens to clients using SSE, because the flow is one-way and HTTP semantics (auth headers, retries, proxies) come for free.
  • Slack and Discord use WebSockets because clients send typing indicators, presence and acknowledgements continuously.
  • Libraries such as Socket.IO historically started with long polling and upgraded to WebSocket when the network allowed it, which is why long polling survives as a fallback.

Failure modes

  • A corporate proxy that buffers responses turns SSE into "nothing, then everything at once"; send periodic comment lines and disable buffering (for nginx, the X-Accel-Buffering header).
  • Long polling can deliver duplicates when a response is lost after the server marked it sent; carry a cursor so the client asks for "after position N".
Check yourself Question 1 of 3
What SSE gives for free recall
From: Comparing Real-Time Protocols

You are streaming LLM tokens from server to browser and considering SSE instead of WebSockets. Which capability does the browser's EventSource give you out of the box that you would otherwise have to design yourself on a WebSocket?

Key Takeaways

Long polling is resource-intensive but works when WebSockets are blocked.
SSE is perfect for unidirectional data streams (like stock tickers).
WebSockets offer full-duplex, low-latency communication for interactive apps.
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue