What is the reason JavaScript setTimeout is so inaccurate?

It’s not supposed to be particularly accurate. There are a number of factors limiting how soon the browser can execute the code; quoting from MDN:

In addition to “clamping”, the timeout can also fire later when the page (or the OS/browser itself) is busy with other tasks.

In other words, the way that setTimeout is usually implemented, it is just meant to execute after a given delay, and once the browser’s thread is free to execute it.

However, different browsers may implement it in different ways. Here are some tests I did:

var date = new Date();
setTimeout(function(e) {
    var currentDate = new Date();
    console.log(currentDate-date);
}, 1000);

// Browser Test1 Test2 Test3 Test4
// Chrome    998  1014   998   998
// Firefox  1000  1001  1047  1000
// IE 11    1006  1013  1007  1005

Perhaps the < 1000 times from Chrome could be attributed to inaccuracy in the Date type, or perhaps it could be that Chrome uses a different strategy for deciding when to execute the code—maybe it’s trying to fit it into the a nearest time slot, even if the timeout delay hasn’t completed yet.

In short, you shouldn’t use setTimeout if you expect reliable, consistent, millisecond-scale timing.

Leave a Comment