The Ultimate Guide to the Event Loop in Node.js

The Ultimate Guide to the Event Loop in Node.js

When learning something new, understanding its fundamentals at a root level is extremely important. In this guide, we’ll explore what the event loop is and how it works behind the scenes in Node.js.

We’ll cover:

  • What the event loop is
  • The phases of the event loop
  • The callback queue
  • How code execution flows with examples

What is an Event Loop?

The event loop is the mechanism that allows Node.js to perform non-blocking I/O operations using a single main thread. It works basically by offloading the operations such as file system, crypto, and timers, etc, to libuv.


How it works

When Node.js executes code, it processes both synchronous and asynchronous operations.

  1. Synchronous code is executed immediately, line by line, by the V8 engine.
  2. When Node.js encounters an asynchronous operation, it delegates that task to libuv, which is responsible for handling non-blocking I/O.

Libuv manages these operations and sends its callback functions to different callback queues.

Meanwhile, the event loop continuously checks whether the V8 call stack is empty. Once the call stack becomes empty, the event loop pulls pending callbacks (based on priority and phase) and pushes them onto the call stack for execution.


Event Loop Phases

The event loop is primarily divided into four important phases:

  1. Timers
  2. Poll
  3. Check
  4. Close callbacks

What happens in each phase?

  • Timers Phase Handles callbacks scheduled by setTimeout() and setInterval().
  • Poll Phase executes most I/O callbacks, such as incoming network connections, data events, file system operations, crypto operations, https.get()
  • Check Phase executes setImmediate() callbacks.
  • Close Phase executes callbacks like socket.on("close").

The Inner Cycle (Microtasks)

Apart from these main phases, there is also a microtask queue that runs:

  • process.nextTick() callbacks
  • Promise callbacks

These microtasks run:

  • At the start of the event loop
  • After every phase

Please review the diagram below to better understand the concepts discussed above.

Article content

Code Example: Execution Flow

Now we will see the code examples to understand how the operations are executed.

const a = 100;

setImmediate(()=> console.log("SetImmediate"));

fs.readFile("file.text","utf8", (err, data) => console.log("File ",data));

setTimeout(()=> console.log("Timeout"), 0);

Promise.resolve().then(()=> console.log("Promise"));

process.nextTick(()=> console.log("NextTick"));

function printA() {
    console.log(a);
}
printA()

console.log("Last line of code")        

Step 1: Execute synchronous code first

The V8 engine runs synchronous lines immediately:

  • printA() → outputs 100
  • console.log("Last line of code")

Output so far:

100
Last line of code        

Step 2: Microtasks (process.nextTick & Promise)

Once synchronous execution finishes, the microtask queue runs:

  1. process.nextTick()
  2. Promise callbacks

Output now becomes:

100
Last line of code
NextTick
Promise        

Step 3: Timers Phase

setTimeout(..., 0) executes next:

Output:
100
Last line of code
NextTick
Promise
Timeout        

Step 4: Check Phase

setImmediate() is executed:

100
Last line of code
NextTick
Promise
Timeout
SetImmediate        

Step 5: Poll Phase

Finally, once the event loop enters the Poll phase again, the fs.readFile callback runs:

Final output:

100
Last line of code
NextTick
Promise
Timeout
SetImmediate
File Hello World        

The event loop may seem complex at first, but once you break it down into phases and understand how callbacks are scheduled, everything starts to make sense. By learning how Node.js handles asynchronous operations, you can write cleaner, faster, and more reliable code. Keep experimenting with examples, and you’ll quickly become comfortable with how the event loop affects your application’s behavior.

I hope this article helped you understand the concept of the Node.js event loop, and you found it informative.

Happy coding! 🚀

Hi Sahil Pate nice article! One question about synchronous tasks: if I have an asynchronous task like an API call and a console.log after that, according to your article, the API call goes to "another queue" and Node processes the console.log. After all the phases, the event loop checks if the API call is finished and then returns the response and executes the console.log. Is that right?"

To view or add a comment, sign in

More articles by Sahil Pate

Others also viewed

Explore content categories