Skip to main content
Practice Problems

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

process.nextTick() vs setImmediate()

Both are used to schedule asynchronous callbacks in Node.js, but they operate in different phases of the event loop and have different priorities.


process.nextTick()

Fires immediately after the current operation completes, before the event loop continues to the next phase. It has the highest priority among all async scheduling mechanisms.

js
console.log('1 - start'); process.nextTick(() => { console.log('2 - nextTick'); }); console.log('3 - end'); // Output: // 1 - start // 3 - end // 2 - nextTick

Key characteristics:

  • Executes before any I/O events or timers
  • Runs in the microtask queue (same as resolved Promises)
  • Recursive nextTick can starve I/O — be careful!
js
// ⚠️ This will starve I/O — the callback runs forever function recursiveNextTick() { process.nextTick(recursiveNextTick); } recursiveNextTick(); // setTimeout, setImmediate, I/O will NEVER fire

setImmediate()

Fires on the next iteration of the event loop, specifically in the check phase — after the I/O poll phase completes.

js
console.log('1 - start'); setImmediate(() => { console.log('2 - setImmediate'); }); console.log('3 - end'); // Output: // 1 - start // 3 - end // 2 - setImmediate

Key characteristics:

  • Runs in the check phase of the event loop
  • Does not starve I/O — always yields to pending I/O first
  • Preferred for deferring work to the next iteration

Side-by-side comparison

js
setImmediate(() => console.log('setImmediate')); process.nextTick(() => console.log('nextTick')); Promise.resolve().then(() => console.log('Promise')); // Output (always): // nextTick // Promise // setImmediate

Event Loop Priority Order

PriorityMechanismQueue
1 (highest)process.nextTick()Microtask
2Promise.then()Microtask
3setTimeout(fn, 0)Timers phase
4setImmediate()Check phase

Inside an I/O callback

When called inside an I/O callback, setImmediate always fires before setTimeout:

js
const fs = require('fs'); fs.readFile(__filename, () => { setTimeout(() => console.log('setTimeout'), 0); setImmediate(() => console.log('setImmediate')); }); // Output (always): // setImmediate // setTimeout

When to use which?

Use caseRecommendation
Must run before any I/Oprocess.nextTick()
Defer to next event loop iterationsetImmediate()
After I/O completionsetImmediate()
Emit events after constructorprocess.nextTick()
js
const EventEmitter = require('events'); class MyEmitter extends EventEmitter { constructor() { super(); // Emit after constructor returns so listeners can attach process.nextTick(() => { this.emit('ready'); }); } } const emitter = new MyEmitter(); emitter.on('ready', () => console.log('ready!')); // Works! 'ready!' is printed

Best practice: Use setImmediate() by default. Reserve process.nextTick() for cases where you specifically need to run code before any I/O, and avoid recursive nextTick calls to prevent I/O starvation.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems