SSE, WebSocket or polling: choosing a transport for live updates
You need to push updates to a client. Three transports are available and each is presented as the obvious answer somewhere.
Choose by direction and frequency. Polling suits infrequent updates and is the simplest thing that works. Server-sent events suit a stream flowing one way, from server to client, and survive proxies and reconnection with almost no code. WebSockets are for genuinely bidirectional, high-frequency traffic, and they cost you the operational simplicity of HTTP.
Polling is not a failure mode
Polling every thirty seconds is often correct. It works through every proxy, needs no special infrastructure, fails in ways operators already understand, and scales with ordinary HTTP caching. Reach for something else when the interval you need is short enough that polling becomes wasteful, not before.
What SSE gives you for free
Server-sent events run over plain HTTP, so they pass through proxies and load balancers without configuration. The browser reconnects automatically and resumes from the last event id, which is the part people underestimate: rebuilding that on top of WebSockets is real work.
When WebSockets earn their cost
When the client sends as much as it receives — collaborative editing, a game, a terminal — the full-duplex connection pays for itself. Below that threshold you are usually paying for infrastructure complexity to solve a problem SSE already solved.
The operational difference
Long-lived connections change your capacity model. Each open connection holds resources on every hop, deployments must drain rather than cut, and connection count becomes a metric that matters. Polling turns the same load into ordinary stateless requests.
Transport comparison
Transport comparison
| Polling | SSE | WebSocket |
| Direction | client pulls | server to client | both ways |
| Protocol | HTTP | HTTP | upgraded |
| Auto-reconnect | n/a | built in | you implement it |
| Proxy friendly | always | usually | often needs config |
| Server cost | per request | per connection | per connection |
| Best for | infrequent updates | feeds, progress, logs | editing, games, terminals |
Key facts
- Server-sent events run over plain HTTP and reconnect automatically with resumption from the last event id, which is significant work to reimplement on WebSockets.
- WebSockets earn their operational cost only when the client sends comparably as much as it receives.
- Polling remains correct for infrequent updates and is the only option that behaves like ordinary stateless HTTP under load.
- Long-lived connections change the capacity model: connection count becomes a limiting metric and deployments must drain rather than cut.
- SSE is limited to text and to one direction, so a client that must send frequently needs a second channel or a different transport.
Frequently asked questions
Is SSE obsolete now that WebSockets are universal?
No. It solves a narrower problem with much less machinery, and for one-way streams — progress, logs, notifications — the narrower solution is the better one. Streaming AI responses is commonly SSE for exactly this reason.
How many open connections can one server hold?
Enough that the limit is usually memory per connection and file descriptors rather than the protocol. The number matters less than the fact that it becomes a capacity dimension you did not previously have to plan for.
Can I start with polling and migrate later?
Yes, and it is often the right sequence. Keep the payload shape identical between transports and the migration touches delivery only, not the client logic that consumes updates.
Machine-readable copy of this page:
/guide/choose-sse-websocket-or-polling.md