0Pricing
Node.js Backend Development Bootcamp · Lesson

Why the Event Loop Stalls on CPU-Bound Work

Identify blocking computations and understand why single-threaded JavaScript needs real threads for parallelism.

One Thread to Run Them All

Node.js runs your JavaScript on a single thread. Every request handler, timer callback, and promise continuation takes turns executing on that one thread, coordinated by the event loop.

This design is brilliant for I/O-bound work: while you wait for a database query or an HTTP response, the thread is free to handle other requests. The waiting happens elsewhere (in the OS and libuv's thread pool), not in your JavaScript.

But there is a catch. If a single callback decides to do heavy computation, that one thread is busy crunching numbers and nothing else can run until it finishes. In this lesson we explore exactly why CPU-bound work stalls the event loop.

The Event Loop in One Picture

The event loop is a simple idea: a loop that repeatedly pulls the next ready callback from a queue and runs it to completion before pulling the next one.

  • A timer fires → run its callback.
  • A socket has data → run its callback.
  • A promise resolves → run its continuation.

Crucially, callbacks are cooperative: the loop cannot interrupt a callback in the middle. JavaScript has no preemption. Each callback must voluntarily return to give the loop a chance to do anything else.

const server = require('http').createServer((req, res) => {
  // This callback must RETURN quickly so the loop can serve
  // the next request. The loop won't interrupt it midway.
  res.end('ok');
});

server.listen(3000, () => {
  console.log('Listening on http://localhost:3000');
});

All lessons in this course

  1. Why the Event Loop Stalls on CPU-Bound Work
  2. Spawning Worker Threads and Passing Messages
  3. Sharing Memory with SharedArrayBuffer and Atomics
  4. Building a Reusable Worker Pool for Throughput
← Back to Node.js Backend Development Bootcamp