The Node.js Event Loop and Why Blocking Hurts
Node.js runs your JavaScript on a single main thread. It stays responsive by handing slow work, such as file reads, database calls, and network requests, to the operating system or a thread pool, then running your callback when the result arrives.
The event loop cycles through phases such as timers, pending callbacks, polling for I/O, and check callbacks. Each phase runs the queued callbacks for that phase before moving on. Anything that keeps the thread busy delays every other request.
javascript const http = require('http');
http.createServer((req, res) = { if (req.url === '/slow') { const end = Date.now() + 5000; while (Date.now() < end) { / busy loop blocks everyone / } } res.end('ok'); }).listen(3000);
While /slow spins, a request to / waits too. CPU-heavy work such as image resizing, large JSON parsing, or encryption should move to workerthreads or a separate process.
To see where time goes, start the app with the built-in profiler:
bash node --prof server.js node --prof-process isolate-.log | head -50
Also check event loop lag with perfhooks.monitorEventLoopDelay(). Sustained lag above a few tens of milliseconds is a sign that something synchronous is running too long. Prefer asynchronous APIs such as fs.promises over their Sync variants inside request handlers.