🌐 Polling vs Long Polling vs WebSockets: How Apps Stay Updated Instantly
You open TikTok and new videos appear without refreshing. Discord shows you who's typing before they hit send. Your food delivery app updates the driver's location every few seconds. How do these apps know when something new happens without you pressing a button?
This is the problem of real-time communication between a client (your phone or browser) and a server (the app's backend). The server has new data, but it needs to push that data to you as soon as it arrives.
There are three main ways to solve this: polling, long polling, and WebSockets. Each has different trade-offs, and picking the wrong one means wasted bandwidth, slower updates, or more complicated infrastructure. This article breaks down how each technique works, when to use it, and why the industry moved from one to the next.
A Quick Refresher on HTTP
Before comparing approaches, it helps to understand the default behavior of HTTP, the protocol that powers the web.
HTTP was designed for a simple request-response model. Your browser sends a request (GET, POST, PUT, DELETE) and the server sends back a response. Once the response is delivered, the connection is closed. This works perfectly for loading a webpage or submitting a form, but it creates a problem for real-time updates: the server cannot initiate a conversation. It can only reply when asked.
This is where polling and its alternatives come in. They are all workarounds for the fact that HTTP was originally designed for documents, not live conversations.
Polling: Just Keep Asking
Polling is the simplest and most straightforward approach. The client sends a request to the server at regular intervals and asks "is there anything new?" If there is new data, the server returns it. If not, the server returns an empty response. The client waits a few seconds, then asks again.
// Simplified polling implementation
function pollForUpdates() {
setInterval(async () => {
const response = await fetch('/api/notifications/latest');
const data = await response.json();
if (data.length > 0) {
updateUI(data);
}
}, 5000); // Ask every 5 seconds
}
Where polling is used today: Status dashboards, monitoring tools, some early social media features.
The obvious problem: Most requests return nothing. You are sending HTTP headers, establishing TCP connections, parsing responses, and discarding them, only to repeat the whole process seconds later. If you have 100,000 users polling every 5 seconds, your server is handling 20,000 requests per second for almost zero useful data.
"Polling creates an enormous amount of unnecessary load on the server," writes Martin Kleppmann in Designing Data-Intensive Applications (2017). "Most of the time, there is nothing new to report, so the requests are wasted."
When polling makes sense: The simplicity is its strength. For internal dashboards with a handful of users, or for apps where 10-30 second delays are acceptable, polling is perfectly fine. You do not need WebSockets for an admin panel that refreshes every 30 seconds.
Long Polling: Making the Server Wait
Long polling improves on naive polling by reversing the timing. Instead of the server responding immediately with "nothing new," the server holds the request open until there is actually something to return. The client sends a request, the server keeps the connection alive, and only responds when new data arrives. Then the client immediately sends another request.
// Simplified long polling implementation
async function longPoll() {
while (true) {
// This request hangs open on the server until data arrives
const response = await fetch('/api/notifications/long-poll');
const data = await response.json();
updateUI(data);
// Immediately start the next long poll
}
}
Long polling was the standard approach before WebSockets became widely supported. It was used by early chat applications, real-time collaboration tools, and social media feeds.
The trade-off: Long polling reduces the number of wasted responses, but it still requires the client to repeatedly establish new HTTP connections. Each connection involves TCP handshakes, HTTP header parsing, and TLS negotiation if HTTPS is used. The server also needs to maintain a pool of open connections, which consumes memory and file descriptors.
"Long polling is a hack," writes Sam Ruby, one of the original contributors to the HTTP specification. "It works, but it works around the limitations of HTTP rather than extending it."
The timeout problem: Servers typically impose a timeout on how long a connection can remain idle. If the timeout is 60 seconds and no data arrives in that time, the server returns an empty response, and the client has to reconnect. This creates a periodic burst of reconnection traffic known as the "thundering herd" problem, especially when thousands of clients' timeouts expire at the same time.
WebSockets: A Persistent Two-Way Channel
WebSockets, standardized in 2011 as RFC 6455, solve the problem differently: instead of simulating real-time communication over HTTP, they upgrade an HTTP connection into a persistent, full-duplex channel.
The handshake starts as an ordinary HTTP request:
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbLi1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13
If the server supports WebSockets, it responds with:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
After this handshake, the connection is no longer HTTP. Both the client and server can send messages at any time, with very low overhead — just a few bytes of framing per message compared to full HTTP headers on every request.
// Client-side WebSocket
const socket = new WebSocket('wss://chat.example.com');
socket.onmessage = (event) => {
const message = JSON.parse(event.data);
displayMessage(message);
};
socket.onopen = () => {
socket.send(JSON.stringify({ type: 'join', room: 'general' }));
};
Where WebSockets shine: Chat applications (Discord, Slack), real-time collaboration (Google Docs), live gaming, live trading platforms, and any app where sub-second latency matters.
The cost: WebSockets are stateful. Each connection consumes a persistent TCP socket on the server, which means memory usage scales linearly with the number of connected clients. A server handling 100,000 concurrent WebSocket connections needs significantly more resources than one handling 100,000 short-lived HTTP requests. As Kleppmann notes, this is why "WebSocket servers often use event-driven architectures (like Node.js or Netty) to handle large numbers of concurrent connections efficiently."
Choosing the Right Approach
The decision between polling, long polling, and WebSockets depends on three factors: latency requirements, scale, and infrastructure complexity.
Choose polling when:
- Updates every 10-30 seconds are acceptable
- You have a small number of users (internal tools, dashboards)
- You want the simplest possible implementation
- Example: An admin panel that refreshes every 30 seconds
Choose long polling when:
- You need near-real-time updates but cannot use WebSockets
- Your users are behind restrictive corporate firewalls that block WebSockets
- You need sub-5-second latency but can tolerate some connection churn
- Example: An early-stage chat app or notification system
Choose WebSockets when:
- You need sub-second latency
- You have a large number of concurrent users
- Both client and server can maintain persistent connections
- You are building a new application from scratch
- Example: Discord, Google Docs, real-time gaming
Summary
| Aspect | Polling | Long Polling | WebSockets |
|---|---|---|---|
| Connection model | Short-lived, repeated | Short-lived, held open | Persistent, full-duplex |
| Latency | 5-30 seconds | < 5 seconds | < 100ms |
| Server load (per user) | High (many requests) | Medium (open connections) | Medium-Low (persistent sockets) |
| Implementation complexity | Trivial | Moderate | Moderate-High |
| Firewall traversal | Works everywhere | Works everywhere | May be blocked |
| Best for | Dashboards, monitoring | Early chat, notifications | Live apps at scale |
The evolution from polling to long polling to WebSockets is a story of the web growing from a document-serving platform to an application platform. Each approach was a reasonable solution for its time, and each still has a place today. The key is matching the communication style to the problem, not using WebSockets for everything just because they are modern.
---
Sources
- RFC 6455, "The WebSocket Protocol", Internet Engineering Task Force, December 2011. https://datatracker.ietf.org/doc/html/rfc6455
- Kleppmann, M., Designing Data-Intensive Applications, O'Reilly Media, 2017. Chapter 11 covers polling, long polling, and streaming approaches in depth.
- Ruby, S., "The WebSocket Protocol", presentation at various conferences, 2011-2012. Discusses the motivation for WebSockets as an extension of HTTP.
- Lubbers, P., Albers, B., and Salim, F., Pro HTML5 Programming, Apress, 2011. Chapter 5 covers WebSocket implementation patterns.