Polling vs Long Polling vs WebSockets: What's the Difference?
Your users want real-time updates. New messages, live notifications, stock price changes -- waiting isn't an option. But how does the server tell the client about new data? The client can't just wait around. HTTP is a one-way protocol: the client asks, the server responds. You have three main options. Each one involves different trade-offs in latency, bandwidth, and complexity.
Key sources: WebSocket RFC 6455, "Designing Data-Intensive Applications" by Martin Kleppmann, and real-world patterns from Slack, Discord, and Firebase.
Polling (Short Polling)
The simplest approach. The client sets an interval (every 5 seconds, every 30 seconds) and sends an HTTP GET request. The server responds with whatever data is available (or nothing).
// Client side -- every 5 seconds
setInterval(async () => {
const data = await fetch('/api/messages');
updateUI(data);
}, 5000);
Pros
- Dead simple -- just a
setInterval+fetch - Stateless -- server doesn't remember clients
- Works everywhere -- all browsers, all proxies, all firewalls
Cons
- Wasteful -- most responses are empty. You're burning server CPU and bandwidth for nothing
- High latency -- worst case, you wait the full interval before learning about new data
- Bad at scale -- 10,000 clients polling every 5 seconds = 2,000 requests/second. Most return 204 No Content.
When to use
- Non-critical updates (weather every hour, dashboard every minute)
- Prototypes and MVPs
- When you don't control the server
Long Polling
An improvement. The client sends a request. The server holds the connection open until new data arrives (or until a timeout). Then it responds. The client immediately sends another request.
Client -- Server (hanging GET)
...waits...
Server -- Client (new data)
Client -- Server (new hanging GET)
Pros
- Much lower latency -- data arrives as soon as it's available
- Standard HTTP -- works through proxies and firewalls
- Good fallback -- when WebSockets aren't available
Cons
- Server resource heavy -- each hanging connection consumes memory, threads, and file descriptors
- Still HTTP overhead -- re-establishes TCP + HTTP headers every cycle
- Timeout headaches -- proxies and load balancers kill idle connections
- Message ordering issues -- multiple long polls in flight can deliver messages out of order
When to use
- As a fallback when WebSockets fail
- Moderate real-time needs (IRC-scale chat, notifications)
- Corporate environments with strict proxy policies
WebSockets
The modern standard. After an initial HTTP upgrade handshake, client and server maintain a persistent, full-duplex TCP connection. Either side can send data at any time.
// Client side -- one-time setup
const ws = new WebSocket('wss://api.example.com/ws');
ws.onmessage = (event) => {
updateUI(JSON.parse(event.data));
};
Pros
- True real-time -- sub-100ms delivery
- Efficient -- no HTTP headers on every message, minimal framing overhead (2 bytes per frame)
- Bidirectional -- server can push, client can send without asking
- Scalable -- one server can handle 100K+ concurrent WebSocket connections
Cons
- Stateful -- you need sticky sessions or a shared state layer (Redis pub/sub)
- Complex reconnection -- no built-in auto-reconnect. You must implement it
- Proxy issues -- some enterprise proxies block WebSocket upgrades
- Horizontal scaling -- harder than stateless HTTP. Need a session store
Comparison Table
| | Polling | Long Polling | WebSockets | |---|---|---|---| | Latency | High (up to interval) | Low (near real-time) | Very low (sub-100ms) | | Server load | Very high (many short requests) | High (many open connections) | Moderate (persistent) | | Network overhead | High | Moderate | Low (2 bytes/frame) | | Complexity | Low | Medium | Medium-High | | Proxy friendly | Excellent | Excellent | May be blocked | | Bidirectional | No | No | Yes | | Stateful | No | Partial | Yes | | Real-world | Weather apps | Facebook chat (original) | Slack, Discord, Figma |
How to Choose
| If you need... | Choose... | |---|:---:| | Simple, non-critical updates | Polling | | A WebSocket fallback | Long Polling | | Chat, gaming, live editing | WebSockets | | Unidirectional server to client (updates) | Consider SSE (Server-Sent Events) | | Peer-to-peer audio/video | WebRTC (not WebSockets) |
Key Takeaways
- Polling = simple but wasteful. Fine for infrequent, non-critical updates.
- Long Polling = lower latency, heavier server. Good fallback.
- WebSockets = true real-time, efficient, bidirectional. The modern standard.
- Always build with fallbacks -- try WebSocket first, fall back to long polling if it fails.
When asked "How would you build a real-time feature?", start by asking: "What's the latency requirement?" If less than 1 second, WebSockets are the answer. If minutes, polling suffices. And always mention fallback strategies.