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
| # | Phase | What it does | Example callbacks |
|---|---|---|---|
| 1 | timers | Runs callbacks from setTimeout() and setInterval() | setTimeout(cb, 0) |
| 2 | pending callbacks | Runs certain deferred system callbacks (I/O errors, TCP, etc.) | Socket errors, TCP.onconnection |
| 3 | idle, prepare | Internal libuv phases (not used directly from JS) | - |
| 4 | poll | The main I/O-waiting phase. Runs ready I/O callbacks or waits for new events | fs.readFile(), network events |
| 5 | check | Runs callbacks from setImmediate() | setImmediate(cb) |
| 6 | close callbacks | Runs resource-closing callbacks | socket.on('close'), stream.destroy() |
3. Schematically (in one Event Loop iteration):
┌───────────────────────────────────────┐
│ 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.
| Function | Where it runs | Roughly when |
|---|---|---|
setTimeout(cb, 0) | timers | At the start of the next Event Loop cycle |
setImmediate(cb) | check | At the end of the current Event Loop cycle |
Example:
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));The result can be:
timeout
immediateor:
immediate
timeoutIt 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:
process.nextTick()runs before microtasks.- Microtasks (
Promise.then,queueMicrotask). - Then it moves to the next Event Loop phase.
6. An example with promises and nextTick
setTimeout(() => console.log('timeout'), 0);
Promise.resolve().then(() => console.log('promise'));
process.nextTick(() => console.log('nextTick'));
setImmediate(() => console.log('immediate'));Result:
nextTick
promise
timeout
immediateWhy:
nextTickandpromiserun through the microtask queue;- then the
timersphase (timeout); - then the
checkphase (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
timersphase; - if not, the Event Loop sleeps, waiting for I/O.
- and timers exist, the Event Loop moves to the
The check phase:
- Runs
setImmediate()callbacks. - If
pollfinished early (with no events), control passes quickly tocheck.
8. The close callbacks phase
Wraps up the cycle:
- runs callbacks tied to closing resources (
close,destroy,disconnect); - for example, after
socket.destroy()orprocess.exit().
9. A simplified view of the full cycle
┌────────────────────────────────────┐
│ 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
| Phase | What it does | Examples |
|---|---|---|
| timers | Runs callbacks from setTimeout / setInterval | setTimeout(cb, 1000) |
| pending callbacks | System callbacks from I/O operations | TCP, DNS |
| idle, prepare | Internal libuv housekeeping steps | - |
| poll | Waits for I/O, handles its callbacks | fs.readFile, net, http |
| check | Runs setImmediate | setImmediate(cb) |
| close callbacks | Closing resources | socket.on('close') |
| microtasks | Between-phase tasks | Promise.then(), process.nextTick() |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.