Blocking vs Non-Blocking Code in Node.js

Learning web development in public. Writing simple, real-world explanations about web development concepts. Helping beginners understand why things work, not just how.
Search for a command to run...

Learning web development in public. Writing simple, real-world explanations about web development concepts. Helping beginners understand why things work, not just how.
No comments yet. Be the first to comment.
Every day, millions of users upload photos, videos, stories, and reels to Instagram. From a user's perspective, the process appears simple: select media, apply filters, add a caption, and tap "Post."
Building Offline-First Messaging Apps: How Messages Work Without Internet Modern messaging applications have transformed the way people communicate. Whether it's chatting with friends, collaborating w
In this article we'll explore about the Expo Router and React Navigation and answer which one to use in 2026. If you build mobile apps using React Native, one thing becomes obvious very quickly: Navig

Modern mobile apps are no longer just a collection of screens connected together. Apps like Instagram, WhatsApp, Uber, and Netflix operate at massive scale with millions of users, real time systems, o
In this article we'll be exploring react.js and the things of react.js that makes it popular and stand out among other libraries ( no fight over library vs framework ). We'll go through: What problem

Shkaai
68 posts
When working with Node.js, one of the most important concepts to understand is the difference between blocking and non-blocking code. This directly affects how fast and scalable your application will be.
Let’s break it down in a simple and practical way.
Blocking code is when a task stops the execution of the program until it is finished.
In simple terms:
The system waits
Nothing else can run during that time
const fs = require('fs');
const data = fs.readFileSync('file.txt', 'utf-8');
console.log(data);
console.log('This runs after file is read');
File is read completely first
Only then the next line runs
This blocks the main thread.
Non-blocking code allows the program to continue executing while a task is running in the background.
Instead of waiting:
The task is started
The program moves forward
Result is handled later
const fs = require('fs');
fs.readFile('file.txt', 'utf-8', (err, data) => {
console.log(data);
});
console.log('This runs before file is read');
File reading starts
Program continues immediately
Result is printed later
In Node.js, everything runs on a single thread.
If one request uses blocking code:
It stops the thread
Other requests must wait
User A → file read (blocking)
User B → simple request
User B will have to wait until User A’s task is finished.
This leads to:
Slow response times
Poor scalability
Bad user experience
Node.js is designed to use asynchronous (async) operations.
Instead of blocking:
Tasks are handled in the background
Callbacks, Promises, or async/await are used
const fs = require('fs/promises');
async function readFile() {
const data = await fs.readFile('file.txt', 'utf-8');
console.log(data);
}
readFile();
console.log('This runs first');
Even though await looks like it pauses execution, Node.js is still handling it efficiently without blocking other operations.
Blocking:
fs.readFileSync('data.txt');
Non-blocking:
fs.readFile('data.txt', callback);
Blocking (bad practice):
Non-blocking (correct approach):
db.query('SELECT * FROM users', (err, result) => {
console.log(result);
});
Or using async/await:
const users = await db.query('SELECT * FROM users');
Non-blocking example:
fetch('/api/data')
.then(res => res.json())
.then(data => console.log(data));
console.log('Runs immediately');
Blocking code stops execution until a task finishes
Non-blocking code allows other tasks to run in parallel
Blocking operations slow down Node.js servers
Node.js is built around asynchronous, non-blocking behaviour
Real-world applications rely heavily on non-blocking code
Understanding blocking vs non-blocking code is essential for writing efficient Node.js applications. Since Node.js uses a single-threaded model, blocking operations can freeze the entire server and delay all incoming requests. Non-blocking code solves this by allowing tasks to run in the background while the system continues processing other requests. By using asynchronous patterns like callbacks, promises, and async/await, you can build fast, responsive, and scalable applications that handle multiple users efficiently.