event-loopAnswer last reviewed July 2026

How much can you actually trust a Node timer? I set a setTimeout for 100 milliseconds and it fires at 340. Why? And while we're here, what do ref and unref really change?

Knows the timer guarantee is one-sided, never early with no bound on lateness, and reasons about ref counting and drift from how the loop schedules

What an AI-prepared candidate might say

So a setTimeout in Node really only promises a lower bound. It's saying run this callback no sooner than 100ms from now, and that's about it. The event loop checks timers once per iteration, so if the process is busy running other callbacks or collecting garbage, the timer just fires late. Firing at 340ms means the loop stayed occupied for something like 240ms past the due time, usually because some synchronous work blocked it. setInterval behaves the same way, which is why intervals drift under load. Timers also keep the Node process alive by default. Calling unref() tells Node to stop holding the process open just for that timer, which is useful for background stuff like periodic cache cleanup, where you don't want a housekeeping timer keeping the process running after everything else is done.

Senior
Locked

The scheduling mechanics behind that 340ms. Due times checked once per loop iteration, the 1ms clamp, and the re-arming rule that decides what an interval does about the periods the loop slept through.

Unlock the depth
Staff
Locked

Why 100k concurrent request timeouts cost close to nothing, thanks to per-duration timer lists, plus timer slippage as a free health metric and the unref'd-interval shutdown bug.

Unlock the depth
Follow-up chain
How much can you actually trust a Node timer? I set a setTimeout for 100 milliseconds and it fires at 340. Why? And while we're here, what do ref and unref really change? | NodeBook