Skip to the solution
HardDSA6 min read

What is process.nextTick() and setImmediate() and when to use them?

1.2k views

The problem

Question presented to candidate: "Both process.nextTick() and setImmediate() schedule a callback to run 'soon' rather than synchronously. What is actually different about them, and can you prove it rather than just state it?"

What a strong answer should cover:

  • process.nextTick(fn) schedules fn onto a microtask queue that is drained completely, including anything it recursively schedules, before the event loop proceeds to its next phase. It runs before Promise microtasks, and before any timer or I/O callback.
  • setImmediate(fn) schedules fn to run in the check phase β€” a real, distinct stop the event loop makes on every lap, after the poll (I/O) phase.
  • πŸ“Œ The verifiable, not just definitional, distinction: because nextTick is a microtask queue, an unbounded recursive process.nextTick() call can starve the event loop entirely β€” I/O callbacks never get a turn, because the loop never advances past the microtask-draining step. The identical recursive pattern using setImmediate() cannot do this, because check is a real phase that only runs once per lap, always preceded by a poll-phase visit.
  • Relative to setTimeout(fn, 0): inside an I/O callback, setImmediate is guaranteed to run before a setTimeout(fn, 0) scheduled at the same point, because poll transitions to check before looping back to timers. At the top level of a script, the order between the two is not guaranteed and depends on process startup timing.
  • Practical uses: process.nextTick() is for guaranteeing a callback runs before the event loop continues at all β€” commonly, ensuring an API always calls its callback asynchronously (even when the result is already available) so callers can rely on consistent, never-synchronous behavior. setImmediate() is for deferring work to after the current poll phase, to avoid hogging I/O processing β€” a common choice for breaking up a large synchronous chunk of work into smaller pieces that let I/O interleave.
  • A good answer explicitly avoids over-generalizing "nextTick runs first" into "nextTick is always what you want" β€” the starvation risk above is a real reason to prefer setImmediate for recursive/repeated scheduling.

Clarifying questions expected:

  • "Is this about deferring one callback, or about something that recurses/repeats?" β€” the starvation risk only matters for the latter.
  • "Does the use case need to run before the event loop continues at all, or just after I/O has had a turn?" β€” this is exactly the nextTick-vs-setImmediate decision.

Code / implementation expected: Yes β€” the starvation test (recursive nextTick vs recursive setImmediate, racing a real I/O callback) is the single most convincing, concrete demonstration of the distinction.

  • event loop
  • scheduling
  • asynchronous
  • performance

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

6 min read Β· 8 sections

Read the code

JavaScriptThe starvation test: recursive process.nextTick() vs recursive setImmediate(), racing a real fs.readFile callback
const fs = require("node:fs");

// mode = "nexttick" or "setimmediate"
const mode = process.argv[2];
let count = 0;
const MAX = 200000;
let ioFired = false;

fs.readFile(__filename, () => {
  ioFired = true;
  console.log(`[${mode}] I/O callback fired after ${count} recursive calls`);
});

function recurse() {
  count++;
  if (count >= MAX) {
    console.log(`[${mode}] stopped after hitting the cap β€” ioFired=${ioFired}`);
    process.exit(0);
  }
  if (mode === "nexttick") process.nextTick(recurse);
  else setImmediate(recurse);
}
recurse();

// node script.js nexttick      -> ioFired=false, cap reached, I/O NEVER ran
// node script.js setimmediate  -> "I/O callback fired after 6 recursive calls"

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 114 of 152 in Node.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Node.js questions
Up nextHard

How do you profile CPU usage with --prof, 0x, or clinic.js flame graphs?

Continue