Search code examples
javascriptnode.jstimernpm

Alternatives to setTimeout for node.js


Objective

Discover if there is a more accurate alternative to setTimeout in node.js.

Background

In the process if making a QPS (Queries Per Second) tester app, I discovered that using setTimeout is increasingly inaccurate the smaller the value I need to wait is.

For example, if I call setTimeout(fn, 1), I will not wait exactly 1ms, instead I will wait a random amount of time, that is as close as possible to 1ms. Node.js documentation makes this clear:

The callback will likely not be invoked in precisely delay milliseconds. Node.js makes no guarantees about the exact timing of when callbacks will fire, nor of their ordering. The callback will be called as close as possible to the time specified.

From https://nodejs.org/api/timers.html#timers_settimeout_callback_delay_arg

In reality this translates into waiting 2, 3, or even 4ms when in fact I need to only wait 1ms.

In sum, the usage of setTimeout is unpredictable, as is explained in this other question:

What did I try?

Since setTimeout is highly inaccurate for small values, I need an alternative - a more accurate one.

To try and find this I searched everywhere for alternatives, but the only thing I found was a library called perf-timers.

This library claims that it is faster and lighter than setTimeout, but there is no way to confirm it since the documentation from the project has been removed from GitHub and I believe that the package was abandoned because no updates or notes were added to it since 2012.

Questions

  1. Is there any accurate alternative to node.js setTimeout?

Solution

  • This is mostly a consequence of being at the mercy of the event loop, its callback queue, and your processing power. If you're looking to execute at an exact moment, perhaps you should look to develop in an alternative environment that isn't built around optimizing asynchronous operations.

    The closest you'll get to ~ 1ms calls would be setImmediate() and process.nextTick(). However, neither of these allow you to specify a delay and you'll stil be at the mercy of the event loop but, you won't need to wait for the next loop iteration to process.

    You should read the Node.js guide on timers and the event loop. If after reading that you don't think anything Node is offering in its core is precise enough, than I would look into using a different Language/Framework.