Read more

Your browser might silently change setTimeout(f, 0) to setTimeout(f, 5)

Henning Koch
August 22, 2016Software engineer at makandra GmbH

When you're nesting setTimeout(f, 0) calls, your browser will silently increase the delay to 5 milliseconds after the fourth level of nesting. This is called "timeout clamping".

Illustration online protection

Rails professionals since 2007

Our laser focus on a single technology has made us a leader in this space. Need help?

  • We build a solid first version of your product
  • We train your development team
  • We rescue your project in trouble
Read more Show archive.org snapshot

Deeply nested setTimeout can happen when you're using a non-native Promise polyfill with long chains of then calls.
The native Promise implementation ( Can I use link Show archive.org snapshot ) uses microtasks and is thus not subject to timeout clamping.

If you need short nested timeouts, you can use an setImmediate Show archive.org snapshot polyfill. This employs various hacks to give you access to the microtask queue.

Measuring timeout clamping

Here is a deeply nested setTimeout call:

var start = Date.now();

function printElapsed() {
  var now = Date.now();
  console.log(now - start);
}

setTimeout(function() {
  printElapsed();
  setTimeout(function() {
    printElapsed();
    setTimeout(function() {
      printElapsed();
      setTimeout(function() {
        printElapsed();
        setTimeout(function() {
          printElapsed();
          setTimeout(function() {
            printElapsed();
            setTimeout(function() {
              printElapsed();
              setTimeout(function() {
                printElapsed();
                setTimeout(function() {
                  printElapsed();
                  setTimeout(function() {
                    printElapsed();
                    setTimeout(function() {
                      printElapsed();
                    }, 0);
                  }, 0);
                }, 0);
              }, 0);
            }, 0);
          }, 0);
        }, 0);
      }, 0);
    }, 0);
  }, 0);
}, 0);

This yields the following messages:

2
3
5
6
11
16
20
25
29
33
38

Observe how after 6 the time difference jumps from 2 to 5 milliseconds.

Henning Koch
August 22, 2016Software engineer at makandra GmbH
Posted by Henning Koch to makandra dev (2016-08-22 11:20)