Node.js Event Loop Phases
Implement or sketch code for Node.js Event Loop Phases. Explain the logic, complexity, and pros/cons of this approach.
Answers use simple, clear English.
Quick interview answer
Logic: Node runs libuv phases: timers → pending → idle/prepare → poll → check (setImmediate) → close. process.nextTick and Promise microtasks run between phases and can starve I/O if abused.
Detailed answer
Logic: Node runs libuv phases: timers → pending → idle/prepare → poll → check (setImmediate) → close. process.nextTick and Promise microtasks run between phases and can starve I/O if abused. Complexity notes included in code section when present. Pros: Single-threaded model simplifies reasoning; non-blocking I/O scales connection count. Cons: CPU-bound work blocks the loop; microtask flooding delays timers. Core: Node runs libuv phases: timers → pending → idle/prepare → poll → check (setImmediate) → close. process.nextTick and Promise microtasks run between phases and can starve I/O if abused. Real-time example: API server: heavy sync JSON.parse in request handler blocks the poll phase and delays all concurrent connections. Pros: Single-threaded model simplifies reasoning; non-blocking I/O scales connection count. Cons: CPU-bound work blocks the loop; microtask flooding delays timers. Common mistakes: Assuming setTimeout(0) runs before setImmediate always (order varies at startup). Best practices: Offload CPU work to worker_threads; never block the event loop in hot paths. Audience level: Senior.
Full explanation
Node runs libuv phases: timers → pending → idle/prepare → poll → check (setImmediate) → close. process.nextTick and Promise microtasks run between phases and can starve I/O if abused.
Real example & use case
API server: heavy sync JSON.parse in request handler blocks the poll phase and delays all concurrent connections.
Pros & cons
Pros: Single-threaded model simplifies reasoning; non-blocking I/O scales connection count. Cons: CPU-bound work blocks the loop; microtask flooding delays timers.
Code example
console.log('start');
setTimeout(() => console.log('timer'), 0);
setImmediate(() => console.log('immediate'));
Promise.resolve().then(() => console.log('microtask'));
process.nextTick(() => console.log('nextTick'));
console.log('end');
// Typical: start, end, nextTick, microtask, timer, immediatePractice code · javascript (view only · no execution)
console.log('start');
setTimeout(() => console.log('timer'), 0);
setImmediate(() => console.log('immediate'));
Promise.resolve().then(() => console.log('microtask'));
process.nextTick(() => console.log('nextTick'));
console.log('end');
// Typical: start, end, nextTick, microtask, timer, immediateCommon mistakes
Assuming setTimeout(0) runs before setImmediate always (order varies at startup).
Best practices
Offload CPU work to worker_threads; never block the event loop in hot paths.
Follow-up questions
- How would you test Node.js Event Loop Phases?
- What metrics prove Node.js Event Loop Phases is healthy in prod?
- How does Node.js Event Loop Phases change at 10× traffic?