JavaScript

Polling with SetInterval Vs SetTimeout in JavaScript

Polling is a simple way to keep the UI updated with the latest data, without the need to refresh the page. In JavaScript, we can use two…

Fotis Adamakis
Fotis Adamakis
Senior Software Engineer / Technical Writer
4 min read
February 5, 2024

Polling with SetInterval Vs SetTimeout in JavaScript

Polling with SetInterval Vs SetTimeout in JavaScript

Polling is a simple way to keep the UI updated with the latest data, without the need to refresh the page. In JavaScript, we can use two main tools: setInterval() and setTimeout(). They both can run code again and again, but they work in slightly different ways.

SetInterval

setInterval() is used to repeatedly call a function with a fixed time delay between each call. It continues to call the callback function until clearInterval() is called or the window is closed.

// Polls every 2 seconds
const intervalID = setInterval(fetchDataAndUpdateUI, 2000);

// To stop polling
clearInterval(intervalID);

We set up a function call fetchDataAndUpdateUI() every two seconds. While it’s straightforward to implement, using setInterval() it can be risky if the function execution time exceeds the interval delay, potentially leading to queued calls. For example, if fetchDataAndUpdateUI() takes longer than two seconds to complete the next call scheduled will still be executed. This can lead to a new call starting before the previous one has finished which results in memory and performance issues, as the number of uncompleted tasks stacks up and will slow down or even crash your application. Additionally, the UI can get out of sync which makes managing loading and error states problematic.

setTimeout

setTimeout, on the other hand, schedules a single call to a function after a specified delay. Unlike setInterval, it does not continue calling the function unless it is explicitly re-scheduled within the function itself. This can be more manageable and safer when dealing with operations that might take varying amounts of time. 
Here’s how you might set up polling with setTimeout:

function fetchDataAndUpdateUI() {
  // Fetch data and update the UI
  // Then, schedule the next update
  setTimeout(fetchDataAndUpdateUI, 2000);
}

// Start polling
setTimeout(fetchDataAndUpdateUI, 2000);

Recursive setTimeout() ensures there’s always a fixed delay between operations, avoiding the risk of call stacking seen with setInterval(). It is generally more flexible and safer for polling, especially when the request frequency needs to be dynamically adjusted.

Alternatives

Both setTimeout and setInterval can provide a near-real-time experience, but they can lead to unnecessary network traffic and server load, especially if the polling frequency is high and the likelihood of data changes is low.

There are two alternatives that require a bit more work on the server side but are much more efficient with the network traffic.

Long polling is a variation of the traditional polling technique that allows for more efficient communication between a client and a server. Instead of making a new request at regular intervals, the client makes a request to the server and the server holds that request open until new data is available. Once the data becomes available, the server responds and sends the new information to the client. After receiving the update, the client immediately sends another request, and the process repeats. This creates a near real-time experience without the constant server queries of traditional polling.

The main advantage is a reduction in network traffic and server load, as requests are only made when changes occur. However, long polling can still keep server connections open for extended periods and can be less scalable under high load.

To implement long polling the client makes an API call and waits until it is fulfilled.

async function longPolling() {
  try {
    // Wait for the fetch to resolve
    const response = await fetch("/updates");
    console.log("Data received:", response);
  } catch (error) {
    console.error("Error during long polling:", error);
    // Optionally implement a backoff strategy before retrying
  } finally {
    // Schedule the next poll
    setTimeout(longPolling, 2000);
  }
}

// Initiate the long polling
longPolling();

The server is a bit more interesting. In the following example using Express.js we have a function checkForUpdates that “flips a coin” to determine if new data exist. If so it returns them, but if not it calls itself again after 2 seconds until the result of hasUpdates will be true.

const express = require("express");
const app = express();

app.get("/updates", (req, res) => {
  const checkForUpdates = () => {
    const hasUpdates = Math.random() > 0.5; // Randomly decide if there are updates

    if (hasUpdates) {
      res.json({ message: "Here is some new data!" });
    } else {
      // No updates, so check again after 2 seconds
      setTimeout(checkForUpdates, 2000);
    }
  };

  checkForUpdates();
});

const server = app.listen(3000);

WebSockets is another alternative that provides a more advanced solution for real-time communication. Unlike long polling, where the connection is held open and re-established with each piece of new data, WebSockets create a persistent, two-way communication channel between the client and server once opened. This allows data to be sent from the server to the client at any time, instantly, without any need from the client to request it. WebSockets are ideal for applications that require constant data updates or real-time user interaction, such as chat applications, live sports updates, or collaborative editing platforms. They offer a more efficient use of server resources, lower latency, and better overall performance compared to long polling. However, implementing WebSockets can be more complex and may require additional considerations for scalability and compatibility with older browsers or proxies.

A dedicated article about WebSockets is coming up, make sure to subscribe for updates (pun indented).

Conclusion

To sum up, prefer SetTimeout over SetInterval to implement polling to avoid queued calls. To optimise network traffic consider long polling. On a high-traffic application, webSockets are the optimal solution for real-time communication.

Fotis Adamakis

Fotis Adamakis

Senior Software Engineer / Technical Writer

Experienced software engineer writing about front end architecture, accessibility, system design, and developer productivity. Lessons from building and maintaining large-scale frontend applications, with a focus on practical patterns that make codebases easier to understand, scale, and evolve.

Barcelona, Spain