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
setTimeoutandsetIntervalcallbacks - 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
setImmediatecallbacks - 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