Blocking vs Non-Blocking Code
Lets understand block in terms of Real life examples

Frontend Developer π» | Fueled by curiosity and Tea β | Always learning and exploring new technologies.
Blocking
Who better know than us, what blocking means. Sad story...
Whether itβs your ex-girlfriend or your Node.js server, being blocked fundamentally ruins everyone's day.
Symptoms of Blocking
Timer Freeze.
Callbacks waiting..
Non Blocking
Opposite of blocking. It's smooth process.
Example
Blocking (synchronous)
const fs = require('fs');
console.log('Before read');
const data = fs.readFileSync('./data.txt', 'utf8'); // β thread stops here
console.log(data);
console.log('After read');
Before read
[file contents]
After read
The entire thread pauses at readFileSync. If this file is on a slow disk, or it's a large file, your server is frozen for that entire duration. Every other user waiting on your server waits too.
Non-blocking (asynchronous) file read:
const fs = require('fs');
console.log('Before read');
fs.readFile('./data.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data); // β runs when the file is done reading
});
console.log('After read'); // β runs IMMEDIATELY, doesn't wait
Before read
After read
[file contents]
This confuses developers the first time they see it. "After read" prints before the file contents? Yes. Because the file read is happening in the background. The callback fires later, when the OS has finished reading. The thread kept running after registering the callback.
This reordering of output is the most reliable indicator that code is truly non-blocking.
Why Blocking Slows Servers:
Let's say your server handles a request that reads a 10ms file. Ten milliseconds sounds nothing. But under load, it compounds fast.
With blocking code:
User A request arrives β file read starts β [10ms frozen] β response sent
User B request arrives β queued, waiting while A is frozen
User C request arrives β queued, waiting while A is frozen
...
If 100 users hit this endpoint simultaneously and each file read takes 10ms, the last user waits 1000ms β 1 full second β not because their file read took that long, but because they're waiting for 99 people ahead of them to get their turn on a frozen thread.
With non-blocking code:
User A request arrives β readFile registered β callback queued β thread free
User B request arrives β readFile registered β callback queued β thread free
User C request arrives β readFile registered β callback queued β thread free
...
All file reads happen in parallel at OS level
All callbacks fire roughly at t=10ms
All responses sent near-simultaneously
Same 100 users. Total wait time: ~10ms for everyone. Not 1000ms. The non-blocking version is 100x faster in this scenario β not because the disk ran faster, but because the thread stopped waiting.
What "Async" Means in Practice
You'll see "async" used interchangeably with "non-blocking" in the Node.js world. They're not quite identical, but in practice the distinction rarely matters for application code.
Node.js gives you three ways to write non-blocking code, and they've evolved over time:
Callbacks (original Node.js style)
fs.readFile('./file.txt', 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
Promises
const fs = require('fs').promises;
fs.readFile('./file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));
Async/Await (modern Node.js)
const fs = require('fs').promises;
async function readMyFile() {
try {
const data = await fs.readFile('./file.txt', 'utf8');
console.log(data);
} catch (err) {
console.error(err);
}
}
readMyFile();
Summary
Blocking code freezes your entire server. Non-blocking code keeps your server responsive even under load. This isn't just good practice in Node.js it's the foundational contract that makes the single-threaded model work.
The Sync functions exist. Use them only when you're not handling concurrent requests (scripts, startup, CLI tools). In a running server, they're almost always a bug waiting to manifest under load.
Async/await is the cleanest way to write non-blocking code today. Under the hood it's still callbacks and promises but the syntax keeps your code readable while the event loop stays unblocked.
Write non-blocking code, and Node.js rewards you with performance that surprises people who've only ever used thread-per-request servers.
Iβm currently deep-diving into the JavaScript, building projects and exploring the internals of the web. If you're on a similar journey or just love talking about JavaScript, letβs stay in touch!
Connect on LinkedIn: Satpalsinh's Profile
Follow my Blog: blogs.satpal.cloud
Keep coding and keep building.






