WebSocket vs Server-Sent Events vs long polling
Chat, live scores and notifications need the server to push data. Compare the three main ways and see how to scale connections.

HTTP is request and response: the client asks, the server answers. For live features the server must push. There are three main options.
Short and long polling
- Polling: the client asks every few seconds. Simple, but wasteful and delayed.
- Long polling: the client asks, and the server holds the request open until it has news, then answers and the client asks again. Works everywhere, but each message costs a new request.
Server-Sent Events (SSE)
A normal HTTP response that stays open, with content type text/event-stream. The server sends events whenever it wants. The browser's EventSource handles it and reconnects automatically.
- Direction: server to client only.
- Good for: notifications, live feeds, dashboards, progress bars.
- Text only, and works over plain HTTP, so proxies and HTTP/2 are friendly to it.
WebSocket
After an HTTP upgrade handshake, the connection becomes a full-duplex channel: both sides can send at any time with very low overhead.
- Good for: chat, multiplayer games, collaborative editing, trading screens.
- You must handle reconnects, heartbeats (ping/pong) and authentication yourself.
Comparison
| Long polling | SSE | WebSocket | |
|---|---|---|---|
| Direction | both (by repeated requests) | server to client | both |
| Overhead | high | low | lowest |
| Auto-reconnect | manual | built in | manual |
| Binary data | yes | no (text) | yes |
| Simplicity | simple | simple | more work |
Scaling real-time connections
Each connection is a long-lived socket, so servers hold many at once. Key points:
- Use a load balancer that supports long connections and sets sensible timeouts.
- A user may be connected to server A while the event happens on server B. Use a pub/sub backplane (Redis, Kafka, NATS) so every server can deliver to its own clients.
- Send heartbeats to detect dead connections.
- Authenticate at connect time and re-check when tokens expire.
Takeaway: if you only push updates down, use SSE. If you need two-way, low-latency messaging, use WebSocket. Fall back to long polling only when you must.
System Design series, Part 2 (building blocks): topic 6 of 14. Previous: Object storage (S3-style): how to store files at scale.


