CPCODELAB
Node.js

The Event Loop

10 min read

The Event Loop

Node.js is single-threaded, but it handles thousands of concurrent connections efficiently using the event loop. The event loop is a mechanism that continuously checks for pending callbacks, I/O events, timers, and resolved Promises, running them one at a time.

When you call an async operation like fs.readFile, Node.js delegates it to the OS (via libuv). The event loop is free to handle other work. When the file read completes, the OS notifies libuv, which queues your callback. The event loop picks it up on its next iteration.

  • timers — executes setTimeout and setInterval callbacks
  • I/O callbacks — most I/O completions (network, file)
  • idle/prepare — internal Node.js use
  • poll — waits for new I/O events to arrive
  • check — executes setImmediate callbacks
  • close callbacks — cleanup, e.g. socket.on('close', ...)
js
console.log("1 - synchronous");

setTimeout(function() {
  console.log("3 - setTimeout (timers phase)");
}, 0);

setImmediate(function() {
  console.log("4 - setImmediate (check phase)");
});

Promise.resolve().then(function() {
  console.log("2 - microtask (Promise)");
});

console.log("Still 1 - synchronous");

// Output order:
// 1 - synchronous
// Still 1 - synchronous
// 2 - microtask (Promise)
// 3 - setTimeout (timers phase)
// 4 - setImmediate (check phase)

Never block the event loop. CPU-heavy loops (while, large JSON.parse, heavy crypto) freeze the entire server. Offload them to worker_threads or a separate process.

Ready to test yourself?
Practice Node.js— quiz & coding exercises