Skip to main content

What phases does the Event Loop consist of?

1. What an Event Loop "phase" is

Node.js's Event Loop is implemented via the libuv library. Each iteration (tick) of the Event Loop is split into phases, logical stages where different types of callbacks run.

One iteration of the Event Loop is called a tick. Once all phases finish, the cycle starts over, as long as there are tasks.

2. The main phases of the Event Loop

#PhaseWhat it doesExample callbacks
1timersRuns callbacks from setTimeout() and setInterval()setTimeout(cb, 0)
2pending callbacksRuns certain deferred system callbacks (I/O errors, TCP, etc.)Socket errors, TCP.onconnection
3idle, prepareInternal libuv phases (not used directly from JS)-
4pollThe main I/O-waiting phase. Runs ready I/O callbacks or waits for new eventsfs.readFile(), network events
5checkRuns callbacks from setImmediate()setImmediate(cb)
6close callbacksRuns resource-closing callbackssocket.on('close'), stream.destroy()

3. Schematically (in one Event Loop iteration):

javascript
┌───────────────────────────────────────┐ 1. timers │ ← setTimeout(), setInterval() ├───────────────────────────────────────┤ 2. pending callbacks │ ← system callbacks (I/O) ├───────────────────────────────────────┤ 3. idle, prepare │ ← internal libuv phases ├───────────────────────────────────────┤ 4. poll │ ← waiting for and handling I/O events ├───────────────────────────────────────┤ 5. check │ ← setImmediate() ├───────────────────────────────────────┤ 6. close callbacks │ ← socket.on('close'), stream.on('close') └───────────────────────────────────────┘

Then a new iteration (tick) begins.

4. How setTimeout() and setImmediate() relate

A very common interview question.

FunctionWhere it runsRoughly when
setTimeout(cb, 0)timersAt the start of the next Event Loop cycle
setImmediate(cb)checkAt the end of the current Event Loop cycle

Example:

javascript
setTimeout(() => console.log('timeout'), 0); setImmediate(() => console.log('immediate'));

The result can be:

javascript
timeout immediate

or:

javascript
immediate timeout

It all depends on where the code ran from: before or after an I/O callback.

5. The special microtask queue

Besides the Event Loop's phases, there are microtasks, callbacks from:

  • Promise.then() / catch() / finally();
  • process.nextTick().

They don't belong to any phase, but run between phases: after every executed callback, the Event Loop runs all pending microtasks.

Priority order:

  1. process.nextTick() runs before microtasks.
  2. Microtasks (Promise.then, queueMicrotask).
  3. Then it moves to the next Event Loop phase.

6. An example with promises and nextTick

javascript
setTimeout(() => console.log('timeout'), 0); Promise.resolve().then(() => console.log('promise')); process.nextTick(() => console.log('nextTick')); setImmediate(() => console.log('immediate'));

Result:

javascript
nextTick promise timeout immediate

Why:

  1. nextTick and promise run through the microtask queue;
  2. then the timers phase (timeout);
  3. then the check phase (immediate).

7. What's special about the poll and check phases

The poll phase:

  • The Event Loop's main phase.
  • This is where Node.js waits for new I/O events.
  • If the queue is empty:
    • and timers exist, the Event Loop moves to the timers phase;
    • if not, the Event Loop sleeps, waiting for I/O.

The check phase:

  • Runs setImmediate() callbacks.
  • If poll finished early (with no events), control passes quickly to check.

8. The close callbacks phase

Wraps up the cycle:

  • runs callbacks tied to closing resources (close, destroy, disconnect);
  • for example, after socket.destroy() or process.exit().

9. A simplified view of the full cycle

javascript
┌────────────────────────────────────┐ timers (setTimeout, setInterval)├────────────────────────────────────┤ │ pending callbacks (I/O)├────────────────────────────────────┤ │ idle, prepare │ ├────────────────────────────────────┤ poll (waiting for I/O events)├────────────────────────────────────┤ check (setImmediate)├────────────────────────────────────┤ │ close callbacks (closing)└────────────────────────────────────┘ ▲ │ │ ▼ microtasks (Promises, nextTick)

10. Summary

PhaseWhat it doesExamples
timersRuns callbacks from setTimeout / setIntervalsetTimeout(cb, 1000)
pending callbacksSystem callbacks from I/O operationsTCP, DNS
idle, prepareInternal libuv housekeeping steps-
pollWaits for I/O, handles its callbacksfs.readFile, net, http
checkRuns setImmediatesetImmediate(cb)
close callbacksClosing resourcessocket.on('close')
microtasksBetween-phase tasksPromise.then(), process.nextTick()

Short Answer

Interview ready
Premium

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