14 November 2021

The maximum delay for setTimeout

max timeout referee

A funny thing happens in JavaScript if you try to do a really long window.setTimeout(…) in your browser. If you go somewhere over 25 days (such as 1000ms * 60s * 60m * 24h * 25d = 2,160,000,000ms), then you’ll see the callback executes immediately!

window.setTimeout(() => console.log('done!'), 2160000000);
> done!

Taking a look at the MDN Web Docs we see:

Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed integer internally. This causes an integer overflow when using delays larger than 2,147,483,647 ms (about 24.8 days), resulting in the timeout being executed immediately.

We can compute that max 32-bit signed integer value as such: (2^32) / 2 - 1, but hex is a nicer way to represent it in code:

const MAX_32BIT = 0x7fffffff;

While this scenario is uncommon, it’s easy to overlook, since JavaScript will easily go up to 2^53 - 1 (Number.MAX_SAFE_INT). If your code might pass through a delay larger than the max signed 32-bit int, then you can check for it and use recursion to go further:

const MAX_32_BIT = 0x7fffffff;

function safeTimeout(onTimeout, delay) {
  window.setTimeout(() => {
    if (delay > MAX_32_BIT) {
      return safeTimeout(onTimeout, delay - MAX_32_BIT);
    } else {
      onTimeout();
    }
  }, Math.min(MAX_32_BIT, delay));
}

If you want to handle clearTimeout or other approaches, I’ll leave that as an exercise for the reader.

thank u for reading, I like u this much!




Did you find this helpful or fun? paypal.me/mrcoles
comments powered by Disqus

Peter Coles

Peter Coles

is a software engineer living in NYC who is building Superset 💪 and also created GoFullPage 📸
more »

github · soundcloud · @lethys · rss