How does Node.js work

Node.js works on an event-driven, non-blocking I/O model, which makes it lightweight and efficient for handling concurrent operations. Here's a breakdown of how it works under the hood:

1. Single-Threaded Event Loop Architecture

Node.js runs on a single-threaded event loop, but it leverages asynchronous operations and worker threads to handle multiple tasks efficiently.

Key Components:

  • V8 Engine (Google Chrome’s JS engine) → Executes JavaScript code.

  • libuv (C library) → Handles asynchronous I/O operations (file system, network calls).

  • Event Loop → Manages callbacks and executes them in a loop.

  • Worker Pool → Offloads heavy tasks (CPU-bound operations) to separate threads.


2. The Event Loop Explained

The event loop allows Node.js to perform non-blocking operations by delegating tasks and processing callbacks when results are ready.

Phases of the Event Loop:

  1. Timers → Executes setTimeout() and setInterval() callbacks.

  2. Pending Callbacks → Processes I/O-related callbacks (e.g., TCP errors).

  3. Idle, Prepare → Internal use (ignored in most cases).

  4. Poll →

    • Retrieves new I/O events (e.g., incoming HTTP requests).

    • Executes I/O callbacks (e.g., fs.readFile completion).

    • If no events, it waits (blocking here if needed).

  5. Check → Runs setImmediate() callbacks.

  6. Close Callbacks → Handles socket.on('close', ...) events.

Example:

javascript
console.log("Start");

setTimeout(() => console.log("Timeout"), 0);
setImmediate(() => console.log("Immediate"));
fs.readFile("file.txt", () => console.log("File Read"));

console.log("End");

Output Order:
Start → End → Timeout → Immediate → File Read
(Order may vary slightly due to event loop phases.)


3. Non-Blocking I/O

When Node.js encounters an I/O operation (e.g., reading a file, querying a database), it does not wait for the task to complete. Instead:

  1. Delegates the task to the OS kernel (via libuv).

  2. Continues executing other code.

  3. Triggers a callback when the I/O operation finishes.

Blocking vs Non-Blocking Example:

javascript
// Blocking (Synchronous)
const data = fs.readFileSync("file.txt"); // Waits here
console.log(data);

// Non-Blocking (Asynchronous)
fs.readFile("file.txt", (err, data) => { // Continues execution
  if (err) throw err;
  console.log(data);
});
console.log("Next task"); // Runs before file is read


4. Worker Threads for CPU-Intensive Tasks

While Node.js is single-threaded for JavaScript execution, it uses worker threads (via worker_threads module) to offload heavy computations (e.g., image processing, hashing).

Example:

javascript
const { Worker } = require("worker_threads");

const worker = new Worker("./cpu-intensive-task.js");
worker.on("message", (result) => console.log(result));


5. Clustering for Multi-Core Scaling

Node.js can fork multiple processes (using the cluster module) to utilize all CPU cores, improving performance for high-load applications.

Example:

javascript
const cluster = require("cluster");
const os = require("os");

if (cluster.isPrimary) {
  // Fork workers (one per CPU core)
  for (let i = 0; i < os.cpus().length; i++) {
    cluster.fork();
  }
} else {
  // Worker process: Start server
  require("./server.js");
}


6. How Node.js Handles HTTP Requests

  1. Incoming Request → Received by the main thread.

  2. Non-Blocking Processing → If I/O is needed (e.g., DB query), it’s delegated to libuv.

  3. Callback Execution → When the I/O completes, the callback is queued in the event loop.

  4. Response Sent → The callback sends the response.

Visualization:

text
Client Request → Node.js (Event Loop) → Delegates I/O → libuv → OS Kernel  
↓  
Callback Queued → Event Loop Executes → Response Sent


Key Takeaways:

✅ Single-threaded but scalable (via event loop + worker threads).
✅ Non-blocking I/O → Ideal for real-time apps (chat, APIs, streaming).
✅ Event-driven → Uses callbacks, Promises, async/await.
✅ Efficient for I/O-heavy tasks but needs worker threads for CPU tasks.
✅ Scales horizontally using clustering.

To Top