Skip to main content

Command Palette

Search for a command to run...

Blocking vs Non-Blocking Code in Node.js

Updated
3 min readView as Markdown

Blocking code stops the execution of other code until the current task finishes.

This means:

  • the program waits

  • nothing else executes meanwhile

In blocking operations:

the main thread remains busy until the task completes.


Example

console.log("start");

for(let i = 0; i < 1e9; i++) {}

console.log("end");

Output:

start
(wait...)
end

The heavy loop blocks execution.


What Non-Blocking Code Means

Non-blocking code allows other code to continue running while a task is being processed.

Instead of waiting:

  • the task runs asynchronously

  • execution continues

This is one of the core concepts behind Node.js.


Example

console.log("start");

setTimeout(() => {
  console.log("done");
}, 2000);

console.log("end");

Output:

start
end
done

The timer does not block the main thread.


Why Blocking Slows Servers

Servers need to handle many requests at the same time.
If one request blocks execution:

  • other users must wait

  • performance becomes slow

  • scalability decreases

Blocking operations can:

  • freeze request handling

  • delay responses

  • reduce throughput


Example Scenario

Imagine:

  • one user requests a large file

  • server blocks while reading it

During that time:

other incoming requests may also get delayed.
This is why blocking code is bad for high-traffic servers.


Async Operations in Node.js

Node.js uses asynchronous operations to avoid blocking.

Async tasks are handled using:

  • event loop

  • libuv

  • thread pool

Operations like:

  • file reading

  • API calls

  • database queries

  • timers

run outside the main execution flow.

When completed:

  • callbacks/promises are queued

  • event loop executes them later


Example

const fs = require("fs");

fs.readFile("test.txt", "utf-8", (err, data) => {
  console.log(data);
});

console.log("reading file...");

Output:

reading file...
(file content later)

File reading happens asynchronously.


Real-World Examples

File Reading

fs.readFile("data.txt", "utf-8", callback);

Node.js reads the file without blocking the server.


Database Calls

db.findUser(id).then(user => {
  console.log(user);
});

Database requests take time, so they are handled asynchronously.


API Requests

fetch("https://api.example.com")
  .then(res => res.json())
  .then(data => console.log(data));

Network requests are also non-blocking.


Why Non-Blocking is Important

Non-blocking behavior allows Node.js to:

  • handle many users efficiently

  • stay responsive

  • improve scalability

  • avoid wasting resources

This is one of the biggest reasons Node.js is popular for backend development.