AlgoMaster Newsletter

AlgoMaster Newsletter

Polling vs. Long Polling vs. SSE vs. WebSockets vs. Webhooks

Ashish Pratap Singh's avatar
Ashish Pratap Singh
Feb 03, 2026
∙ Paid

Whether you are chatting with a friend or playing an online game, updates show up in real time without hitting “refresh”.

Behind these seamless experiences lies a key engineering decision: how does the server notify the client (or another system) when new data is available?

The traditional HTTP was built around a simple request-response flow: the client asks, the server answers. But in real-time systems, the server often needs to push updates proactively, sometimes continuously.

That’s where communication models like Long Polling, Server-Sent Events (SSE), WebSockets, and Webhooks come in.

In this article, we’ll break down how each one works, it’s pros and cons, where it fits best, and how to choose the right approach for a production system or a system design interview.

Let's start with the most straightforward approach.


1. Polling

Polling is the simplest approach to getting updates from a server. The client sends requests to the server at regular intervals, checking if anything has changed.

Think of it like refreshing your email inbox every few minutes to check for new messages.

How It Works

  1. Client sends an HTTP request to the server

  2. Server responds immediately with current data (or empty response)

  3. Client waits for a fixed interval (e.g., 5 seconds)

  4. Client sends another request

  5. Repeat indefinitely

Notice something wasteful here? The client keeps asking even when nothing has changed. Three out of four requests in this diagram returned empty responses.

In real applications, this ratio is often much worse. You might make 100 requests before getting a single meaningful update.

Example: Weather Dashboard

Imagine you’re building a weather dashboard. Weather data doesn’t change that frequently, maybe every 15-30 minutes at most.

Polling makes sense here:

setInterval(async () => {
    const response = await fetch('/api/weather?city=london');
    const weather = await response.json();
    updateDashboard(weather);
}, 60000); // Poll every minute

Every minute, your client asks for the current weather. The server responds with temperature, humidity, conditions, and so on.

Pros

  • Simple to implement: Just a regular HTTP request in a loop. No special protocols or libraries needed.

  • Works everywhere: Any HTTP client can do polling. No firewall or proxy issues.

  • Stateless: Each request is independent. The server doesn’t need to maintain any connection state.

  • Easy to debug: Standard HTTP requests that show up in network logs and dev tools.

Cons

  • Wasted requests: Most requests return empty responses when nothing has changed. This wastes bandwidth and server resources.

  • High latency: Updates are delayed by the polling interval. If you poll every 10 seconds, updates can take up to 10 seconds to reach the client.

  • Doesn’t scale: 10,000 clients polling every second means 10,000 requests per second, even when nothing is happening.

  • Trade-off between latency and efficiency: Shorter intervals mean faster updates but more wasted requests. Longer intervals mean fewer requests but slower updates.

When to Use

  • Low-frequency updates: Weather data, daily reports, or anything that changes infrequently

  • Simple systems: MVPs, internal tools, or situations where simplicity matters more than efficiency

  • Legacy compatibility: When you need to support older clients or environments that can’t use modern techniques

  • Acceptable latency: When delays of several seconds (or minutes) are acceptable

Polling is a reasonable starting point, but you’ll quickly feel its limitations as your application grows. If you need faster updates without drowning your server in requests, that’s where long polling comes in.


2. Long Polling

Long polling improves on regular polling by having the server hold the request open until new data is available (or a timeout occurs). Instead of the client repeatedly asking “anything new?”, the server waits and responds only when there’s something to report.

This was the technique that powered early real-time applications like Facebook Messenger before WebSockets became widely supported.

How It Works

  1. Client sends an HTTP request to the server

  2. Server holds the connection open (doesn’t respond immediately)

  3. When new data arrives, server sends the response

  4. Client immediately sends another request

  5. If no data arrives within the timeout period, server sends an empty response and client reconnects

The key insight is that the server only responds when it has something meaningful to say. This eliminates the wasted “nothing new” responses of regular polling.

Example: Chat Application

Consider a chat app built with long polling. When you open a conversation, your browser sends a request like:

GET /api/messages?conversation=123&after=msg_999

The server checks if there are any messages newer than msg_999. If not, instead of returning an empty response, it holds the connection and waits.

When someone sends a new message to that conversation, the server immediately responds with the new message. Your client receives it, renders it in the chat window, and immediately opens a new connection to wait for the next message.

There’s an important detail here: the timeout. HTTP connections can’t stay open forever. Proxies, load balancers, and browsers all have limits. So the server needs to respond eventually, even if nothing happened.

A typical timeout is 30 seconds. If 30 seconds pass with no new data, the server sends an empty response, the client immediately reconnects, and the wait continues.

Pros

  • Near real-time: Updates arrive almost instantly when they happen, without waiting for a polling interval.

  • Fewer wasted requests: Responses almost always contain useful data, not empty “nothing new” responses.

  • Works through proxies and firewalls: Uses standard HTTP, so it works in restrictive network environments where WebSockets might be blocked.

  • Simpler than WebSockets: No protocol upgrade, no special handling for connection state.

Cons

  • Resource intensive: Each waiting client holds a connection open on the server. With 10,000 clients, you need 10,000 open connections.

  • Timeout handling complexity: You need to handle timeouts, reconnection logic, and edge cases like the client receiving data just as the timeout expires.

  • Head-of-line blocking: If multiple events happen quickly, they may get batched together or delivered out of order.

  • HTTP overhead: Every response requires a new request, and each request carries HTTP headers. This overhead adds up.

When to Use

  • Chat applications (historically): Before WebSocket support was universal, long polling powered most chat systems

  • Fallback mechanism: When WebSockets aren’t available due to proxy or firewall restrictions

  • Server-initiated updates: When clients mostly receive data rather than send it

  • Moderate scale: Works well for hundreds or thousands of concurrent connections, but gets expensive at massive scale

Long polling feels like “almost real-time,” but it’s still request-response at heart. The client still initiates every exchange. What if the server could just push data to clients whenever it wants? That’s exactly what Server-Sent Events enable.


3. Server-Sent Events (SSE)

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2026 Ashish Pratap Singh · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture