Event Loop, Async Execution & Concurrency
How Node.js schedules asynchronous work, uses Libuv, and handles CPU-intensive workloads.
Q11: What is the Node.js Event Loop and how does it work?
The Event Loop allows Node.js to perform non-blocking I/O operations despite JavaScript being single-threaded. It offloads tasks to the system kernel or Libuv thread pool. It cycles through phases: Timers, Pending Callbacks, Idle/Prepare, Poll, Check, and Close Callbacks.
- The Event Loop enables non-blocking I/O on a single thread.
- Libuv handles asynchronous underlying operations and thread pooling.
Which library manages the Event Loop in Node.js?
Q12: What is the Reactor Pattern in Node.js?
The Reactor Pattern is a design pattern that handles service requests delivered concurrently to a service handler by demultiplexing incoming requests and dispatching them synchronously to associated request handlers.
- Core design pattern behind Node.js non-blocking architecture.
- Uses an event demultiplexer to collect and dispatch async events.
Which component in the Reactor Pattern collects I/O events and pushes them to the queue?
Q13: What is the difference between process.nextTick() and setImmediate()?
process.nextTick() fires immediately after the current operation finishes, before the Event Loop continues to any other phase. setImmediate() schedules callbacks in the Check phase of the Event Loop.
process.nextTick()runs prior to the next Event Loop tick.setImmediate()runs during the Event Loop Check phase.
Which queue does process.nextTick() push callbacks onto?
Q14: What causes Event Loop starvation and how do you fix it?
Event loop starvation happens when long-running synchronous code or continuous microtasks prevent the Event Loop from advancing to pending I/O phases. Break up work using setImmediate().
- Heavy sync loops hold main thread control continuously.
- Offload calculations to Worker Threads or partition iterations using
setImmediate().
How can you partition long synchronous array processing to yield to I/O?
Q15: What is the default size of the Libuv thread pool, and how can it be changed?
The default thread pool size in Libuv is 4. It can be changed by setting the UV_THREADPOOL_SIZE environment variable before starting the application (up to 1024).
- Default thread pool size is 4 threads.
- Configurable using
UV_THREADPOOL_SIZEenvironment variable.
What is the default size of the Libuv thread pool?
Q16: What are Worker Threads in Node.js?
Worker Threads (worker_threads) allow execution of CPU-bound JavaScript operations in parallel threads without blocking the main event loop.
- Worker Threads execute heavy JavaScript operations off the main loop.
- Threads can share memory via
SharedArrayBuffer.
What scenario is best suited for Worker Threads?
Q17: What is Event Loop Delay (Lag) and how can you measure it in production?
Event Loop Delay (or lag) measures the latency between when a timer callback is scheduled to execute and when it actually gets invoked by the Event Loop. High delay indicates that synchronous operations are blocking the main thread, delaying asynchronous task processing. Production metrics can track this using perf_hooks with monitorEventLoopDelay(), which samples execution intervals and generates histogram percentiles (p50, p99) of Event Loop lag.
- Event Loop lag indicates main thread blocking caused by heavy synchronous computation.
perf_hooks.monitorEventLoopDelay()samples and calculates precise latency histograms for monitoring.
Which core Node.js module contains monitorEventLoopDelay() for latency tracking?