Quiz

What is the difference between `setTimeout()`, `setImmediate()`, and `process.nextTick()`?

Topics
Web APIsJavaScript

TL;DR

In Node.js, setTimeout() schedules a timer callback after a minimum delay, setImmediate() schedules a callback for the event loop's check phase after I/O callbacks, and process.nextTick() queues work to be drained after the current JavaScript operation before the event loop continues. Node now marks process.nextTick() as legacy and recommends queueMicrotask() for most userland deferral.

setTimeout(() => console.log('setTimeout'), 0);
setImmediate(() => console.log('setImmediate'));
process.nextTick(() => console.log('nextTick'));

In this example, process.nextTick() will execute first, followed by either setTimeout() or setImmediate() depending on the environment.


Where each callback runs in Node.js

This simplified Node.js view shows the queues or phases associated with each API; it is not a universal ordering guarantee between a zero-delay timer and setImmediate().

Node.js scheduling checkpoints and phases

The relative order of setTimeout(fn, 0) and setImmediate(fn) depends on the surrounding phase and timing, while process.nextTick() runs before the event loop advances.

Difference between setTimeout(), setImmediate(), and process.nextTick()

setTimeout()

setTimeout() is a function that schedules a callback to be executed after a specified delay in milliseconds. The delay is a minimum, not a guarantee, since the callback only runs once the call stack is clear and any earlier tasks have completed. Browsers also clamp the delay to at least 4ms once timers are nested beyond five levels.

setTimeout(() => {
console.log('Executed after at least 1000 milliseconds');
}, 1000);

setImmediate()

setImmediate() is a Node.js API that queues a callback for the check phase, after the poll phase's I/O callbacks. It is not simply a faster setTimeout(0), and their relative order depends on where they were scheduled.

setImmediate(() => {
console.log('Executed after the current event loop phase');
});

process.nextTick()

process.nextTick() adds a callback to Node's next-tick queue. Node drains that queue after the current JavaScript operation completes and before allowing the event loop to continue. Recursively scheduling next-tick callbacks can starve I/O. The API is now marked legacy; prefer the portable queueMicrotask() unless next-tick-specific ordering is required.

process.nextTick(() => {
console.log('Executed before the next event loop iteration');
});

Execution order

The execution order of these functions can be demonstrated with the following example:

setTimeout(() => console.log('setTimeout'), 0);
setImmediate(() => console.log('setImmediate'));
process.nextTick(() => console.log('nextTick'));

In this example, the output will be:

nextTick
setTimeout or setImmediate (order may vary)
setImmediate or setTimeout (order may vary)

In this CommonJS example, process.nextTick() executes first, followed by setTimeout() and setImmediate() in an order that can vary. Do not generalize the first-place rule to ES modules: Node evaluates ES modules through the microtask machinery, which can change ordering relative to process.nextTick().

Further reading

Exercises

Check your understanding
Beta
Check your understanding Exercise
Check your understanding Exercise

Which statements about these Node.js scheduling APIs are correct? Select all that apply.