The event loop in Node.js is a mechanism that allows asynchronous tasks to be handled efficiently without blocking the execution of other operations. It:
- Executes JavaScript synchronously first and then processes asynchronous operations.
- Delegates heavy tasks like I/O operations, timers, and network requests to the libuv library.
- Ensures smooth execution of multiple operations by queuing and scheduling callbacks efficiently.
Why Event Loop is important?
The Event Loop is essential in Node.js because it allows non-blocking, asynchronous operations to be handled efficiently, even though Node.js operates on a single thread.
- Enables non-blocking execution despite Node.js being single-threaded.
- Helps handle I/O-bound tasks efficiently.
- Makes Node.js suitable for scalable applications like web servers.
Let’s see a simple Asynchronous example
JavaScript console.log("This is the first statement"); setTimeout(function() { console.log("This is the second statement"); }, 1000); console.log("This is the third statement");
- First statement is logged immediately.
- setTimeout schedules the second statement to log after 1000 milliseconds.
- Third statement is logged immediately after.
- After 1000 milliseconds, the callback from setTimeout is executed, logging Second statement.
Output
This is the first statement This is the third statement This is the second statement
How the Event Loop Works?
When a Node.js application runs, the event loop starts, processes the synchronous code first, and then moves to handle asynchronous tasks. The execution follows these steps:
1. Initialization
When Node.js starts, it loads the script, executes synchronous code, and registers any asynchronous tasks (e.g., timers, I/O requests, network operations).
2. Execution of Input Script
- The call stack executes synchronous code first.
- Any asynchronous operations (setTimeout, fs.readFile, network requests) are delegated to libuv.
3. Handling Asynchronous Operations with libuv
Node.js uses a special C library called libuv to handle asynchronous operations. This library manages a thread pool that offloads heavy tasks (like file I/O, database operations, or network requests) that would otherwise block the event loop. The thread pool contains several threads that perform tasks like:
- File system I/O (fs.readFile)
- Network requests (HTTP, TCP, DNS)
- Timers (setTimeout, setInterval)
- Compression and cryptographic tasks
4. Callback Execution
Once the thread pool completes its tasks, it sends callbacks to the event queue. The event loop processes these callbacks, but only when the call stack is empty (i.e., when no synchronous code is currently executing).
5. Event Loop Phases
The event loop goes through multiple phases, each designed to handle a different set of operations. It checks for events, handles asynchronous callbacks, and executes tasks in the correct order.
6. Callback Execution from Event Queue
After the call stack is empty, the event loop picks tasks from the event queue and sends them to the call stack for execution. These tasks could include:
- Completing network requests
- Processing I/O events
- Handling timers like setTimeout or setInterval
The following diagram is a proper representation of the event loop in a Node.js server:

Phases of the Event loop
The event loop in Node.js consists of several phases, each of which performs a specific task. These phases include:

1. Timers Phase
This phase processes timers that have been set using setTimeout() and setInterval().
JavaScript console.log('Start'); setTimeout(() => { console.log('Timeout callback'); }, 2000); console.log('End');
- setTimeout() schedules a callback to run after 2000 milliseconds.
- The event loop processes this callback in the timers phase after the synchronous code has executed.
Output:
Start End Timeout callback
2. Pending Callbacks
This phase executes I/O-related callbacks that were deferred from the previous loop cycle.
JavaScript console.log('Start'); setImmediate(() => { console.log('Immediate callback'); }); console.log('End');
- setImmediate() schedules a callback to run immediately after the current event loop cycle.
- The event loop processes this callback in the pending callbacks phase.
Output:
Start End Immediate callback
3. Idle, Prepare (Internal use only)
This phase is used internally by Node.js for background tasks.
4. Poll Phase (Main Phase)
The Poll phase executes most of the tasks like- I/O, file reading, HTTP requests and much more.
JavaScript const fs = require('fs'); const readStream = fs.createReadStream('./file.txt'); console.log('Start'); readStream.on('data', (chunk) => { console.log(chunk.toString()); }); console.log('End');
- fs.readFile() initiates an asynchronous file read operation.
- The callback is added to the poll phase and executed once the file read is complete.
Output:
Start End File read complete
5. Check Phase
This phase processes any setImmediate() callbacks that have been added to the message queue.
JavaScript console.log('Start'); setImmediate(() => { console.log('Immediate callback'); }); console.log('End');
- setImmediate() schedules a callback to run immediately after the poll phase.
- The event loop processes this callback in the check phase.
Output
Start End Immediate callback
6. Close Callbacks Phase
This phase executes callbacks for closed connections like sockets, streams, and event emitters.
JavaScript const net = require('net'); const server = net.createServer((socket) => { socket.on('close', () => { console.log('Socket closed'); }); }); server.listen(8000);
- The server listens for incoming connections.
- When a socket is closed, the ‘close’ event is emitted, and the corresponding callback is executed in the close callbacks phase.
Output
Server listening on port 8000
process.nextTick() and Promises in the Event Loop
Apart from these phases there is also process.nextTick() and promise callback which has the highest priority in the event loop. It executes after every phase before moving to the next phase.
- process.nextTick() callbacks are always executed before the event loop moves to the next phase.
- Resolved Promise callbacks are processed immediately after process.nextTick().
Now you have seen all the phases so let’s understand the order by using this code example
JavaScript setImmediate(() => { console.log("setImmediate is called"); }); Promise.resolve("Promise is resolved").then(console.log); setTimeout(() => { console.log("Time function is called"); }, 0); process.nextTick(() => { console.log("Process.nextTick"); });
OutputProcess.nextTick Promise is resolved Time function is called setImmediate is called
In this example
- process.nextTick() executes before moving to the next phase.
- Resolved Promises execute right after process.nextTick().
- setTimeout() executes in the timers phase.
- setImmediate() executes in the check phase.
Similar Reads
Node.js Events
An event in NodeJS is an action or occurrence, such as a user click, a file being read, or a message being received, that NodeJS can respond to. Events are managed using the EventEmitter class, which is part of NodeJS's built-in events module. This allows NodeJS to react to various actions asynchron
7 min read
NodeJS EventEmitter
The EventEmitter class in NodeJS is a core module that provides a way to handle asynchronous events. It allows objects to emit events and other objects to listen and respond to those events. Event Emitter in NodeNodeJS uses an events module to create and handle custom events. The EventEmitter class
5 min read
NodeJS Introduction
NodeJS is a runtime environment for executing JavaScript outside the browser, built on the V8 JavaScript engine. It enables server-side development, supports asynchronous, event-driven programming, and efficiently handles scalable network applications. NodeJS is single-threaded, utilizing an event l
5 min read
Non-Blocking event loop in Node.js
Node.js operates on a single-threaded, event-driven architecture that relies heavily on non-blocking I/O operations to handle concurrent requests efficiently. This approach is enabled by its event loop mechanism, which allows Node.js to handle multiple requests concurrently without creating addition
5 min read
Event loop in Spring WebFlux
Spring WebFlux is a version of the Spring Framework that supports reactive programming, allowing for non-blocking, asynchronous code execution. At the core of its framework, the event loop model is designed to efficiently handle multiple simultaneous requests. For example, if there are multiple even
5 min read
NodeJS REPL (READ, EVAL, PRINT, LOOP)
NodeJS REPL (Read-Eval-Print Loop) is an interactive shell that allows you to execute JavaScript code line-by-line and see immediate results. This tool is extremely useful for quick testing, debugging, and learning, providing a sandbox where you can experiment with JavaScript code in a NodeJS enviro
5 min read
What is Poll Phase in Node.js Event Loop ?
The Node.js event loop is the heart of Node.js, responsible for executing non-blocking I/O operations and enabling the asynchronous behavior that defines the platform. Among the various phases of the event loop, the poll phase plays a crucial role in handling I/O events. In this article, we'll delve
6 min read
Node.js Process exit Event
The process is the global object in Node.js that keeps track of and contains all the information of the particular node.js process that is executing at a particular time on the machine. The process.exit() method is the method that is used to end the Node.js process. Every process action on the mach
2 min read
React onTouchEnd Event
React onTouchEnd event event fires when the user touches screen and releases the touch. Similar to other elements in it, we have to pass a function for process execution. It is similar to the HTML DOM ontouchend event but uses the camelCase convention in React. Syntax:onTouchEnd={function}Parameter
2 min read
Callbacks and Events in NodeJS
Callbacks and events are fundamental building blocks for asynchronous programming in NodeJS. They're essential for handling operations that might take some time, ensuring your application handles asynchronous operations smoothly. Callback in NodeJSIn NodeJS, Callbacks are functions passed as argumen
3 min read