DEV Community

Cover image for Web Communication: Long Polling Explained
Naveen prasad
Naveen prasad

Posted on

Web Communication: Long Polling Explained

In the previous post, we explored short polling. This time, let’s upgrade to long polling, a technique that keeps the client in sync with the server without frequent re-requests.


🧠 What’s Different?

In long polling:

  • Client sends a request and waits.
  • Server responds only when there is new data.
  • Once response is received, the client immediately resubscribes.

Let’s understand this using the core code blocks involved.


🧩 Server Code Highlights

1. Store connections for later use

const connections = [];

app.get('/subscribe', (req, res) => {
  if (req.query.data !== longPollingData) {
    return res.status(200).json({ message: longPollingData });
  }
  connections.push(res); // hold the response until new data is available
});
Enter fullscreen mode Exit fullscreen mode

If the client already has the latest data, we hold the response (res) for future updates.

Otherwise, respond immediately.

2. Notify all clients on data update

app.post('/updateData', (req, res) => {
  longPollingData = req.body.userInput;

  connections.forEach((connection) => {
    connection.status(200).json({ message: longPollingData });
  });

  connections.length = 0;
  res.send('Update sent to all clients');
});
Enter fullscreen mode Exit fullscreen mode
  • On receiving new data, we loop through all held responses and send the updated message.

  • Then, we clear the connections array.

Client Code Highlights

1. Subscribe and re-subscribe

const subscribe = async (lastData) => {
  try {
    const res = await fetch('/subscribe?data=' + lastData);
    const data = await res.json();

    updateData(data.message);
    await subscribe(data.message); // recursive re-subscribe
  } catch (err) {
    await new Promise((res) => setTimeout(res, 1000));
    await subscribe(lastData); // retry on failure
  }
};
Enter fullscreen mode Exit fullscreen mode
  • Makes a /subscribe request and waits for server update.
  • Once update is received, it recursively re-subscribes.

2. Submit new data

form.addEventListener('submit', async (e) => {
  e.preventDefault();

  const inputValue = document.getElementById('userInput').value;

  await fetch('/updateData', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userInput: inputValue }),
  });

  form.reset();
  updateData(inputValue);
});
Enter fullscreen mode Exit fullscreen mode

Sends new input to server which triggers an update to all subscribed clients.

✅ Summary

Long polling holds client requests until new data is ready.

It’s efficient and feels real-time without setting up a WebSocket.


✅ Conclusion

Long polling offers a smarter alternative to short polling by reducing unnecessary traffic and keeping clients updated with minimal latency. While not as seamless as WebSockets, it's a practical solution for many use cases where persistent connections aren’t viable.


👍 Pros

  • Reduced network traffic compared to short polling.
  • Near real-time data delivery without constant re-requesting.
  • Works with HTTP/1.1, no need for WebSocket support.
  • Simple implementation using standard HTTP methods.

👎 Cons

  • ❌ Each update still requires a new HTTP connection.
  • ❌ More resource-intensive than WebSockets at scale.
  • Delayed response if no data is available for a while.
  • ❌ Not truly bi-directional — only server-to-client.

🕒 When to Use Long Polling

  • You need real-time-like updates, but WebSockets are not an option (e.g., firewalls, older infrastructure).
  • Your app doesn’t need constant updates but should reflect new data quickly.
  • You want a simpler alternative to WebSockets that works in most browsers.

Top comments (0)