Flame_Phoenix Flame_Phoenix - 1 year ago 77
Node.js Question

What happens when setTimeout < 5 node.js


Find out the true behavior of
setTimeout(fn, X)
when X-> 0.


I am developing a tool that makes QPS (Queries Per Second) tests, using
. I was recently surprised when I made a test of 1000 QPS that took roughly 5 seconds to execute when it should have taken 1 (not counting any other external factors).

The tests works fine for lower values of QPS, bellow 100 for example.

While investigating, I found some articles explaining that when making
setTimeout(fn, X)
calls, when X tends to 0, if X is too small, it will get trimmed to a higher value.

An examples of this can be seen in this question from 2011, where the old spec specifies that if
setTimeout(fn, X)
where X <= 3, X will be automatically set to 4.

This means that the minimum amount of time I can ever hope to wait, between two executions of
is 4 milliseconds. If I have
setTimeout(fn, 1)
, it will be converted to
setTimeout(fn, 4)


Every article I see says something different, and in the question I previously posted, different answers say different things as well. The overall all conclusion seems to be "there is no conclusion, as the behavior is highly inconsistent".

Coming back to node.js, and since the questions I pointed is quite old, I would like an update on the following :

  1. One of the answers says that the minimum value of X is 1. Is this still accurate?

  2. How does
    setTimeout(fn, X)
    when X -> 0 work?


I would like more information regarding
so I can build my code around it. Links to documentation and dates of the articles or answers found will be highly appreciated.

Thanks for the help!

Answer Source

It is related to the event loop. Imagine a pile of order, that node.js execute one after another.

setTimeout is (dumbed down version) "put this at the end of the pile, and don't execute it before Xmilliseconds".

So while you are certain it will wait at least that time, you will still need to wait for node.js to get that task back at the top of the pile, which can take a bit of time (in the order of milliseconds).

That's also why it is recommended to use process.nextTick, which put the task at the top of the pile, instead of setTimeout(callback, 0).

So in your example, setTimeout(callback, 1) will not be internally transformed to setTimeout(callback, 4), it's just that there is a 3ms overhead before node.js get back to that task once the timer have elapsed. If there is nothing else in the event loop, and your processor is fast, you may be able to cut down another millisecond, but node.js is just not built to handle time sensitive task at that level. That would put it in the realm of Real Time Programming, which is another use altogether.

To put things in perspective, setTimeout is, in a crushing majority of use case, used to handle a handful of seconds, so ~1000ms. Is 2~3ms more really that much of a inconvenience?

process.nextTick will also allow node.js to clean the event queue, and prevent RangeError: Maximum call stack size exceeded exceptions when you chain a lot of asynchronous calls.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download