Blog/Event Loop Blocking in Node.js: Real Examples and Fixes
Performance

Event Loop Blocking in Node.js: Real Examples and Fixes

7 min read

Event loop blocking is one of the most common and dangerous causes of poor Node.js performance. If your API becomes slow under load, even though your code "looks fine," there is a high chance that something is blocking the event loop.

The problem is not always obvious. Blocking code often looks harmless in code review, but in production it delays every request behind it.

In this guide, we will look at real examples of event loop blocking in Node.js, why they happen, and how to fix them.

What Is Event Loop Blocking?

The Node.js event loop processes one task at a time. As long as each task is small, the system stays fast.

But if one task takes too long, all other requests must wait.

That delay is called event loop blocking.

Example:

  1. Request A starts
  2. It runs heavy work for 200ms
  3. Request B arrives — must wait
  4. Request C arrives — must wait

This is how a single blocking operation can degrade the entire API.

Example 1 — Blocking File System Operations

import fs from "fs";
import type { Request, Response } from "express";

export async function getData(req: Request, res: Response) {
  const data = fs.readFileSync("./large-file.json", "utf8");
  res.json({ data });
}

Why this is a problem

  • readFileSync blocks the event loop
  • all other requests wait
  • latency increases under load

Fix

import { promises as fs } from "fs";

export async function getData(req, res) {
  const data = await fs.readFile("./large-file.json", "utf8");
  res.json({ data });
}

Example 2 — CPU-Heavy Loops

export async function compute(req, res) {
  let result = 0;

  for (let i = 0; i < 100_000_000; i++) {
    result += i;
  }

  res.json({ result });
}

Why this is a problem

  • blocks CPU for a long time
  • event loop cannot process other requests

Fix

  • move heavy computation outside request path
  • precompute results
  • or use background processing

Example 3 — Synchronous Crypto

import crypto from "crypto";

export async function hash(req, res) {
  const hash = crypto.pbkdf2Sync(req.body.password, "salt", 100000, 64, "sha512");
  res.json({ hash });
}

Why this is a problem

  • synchronous crypto is expensive
  • blocks event loop

Fix

Use async crypto methods:

import crypto from "crypto";

crypto.pbkdf2(password, "salt", 100000, 64, "sha512", (err, derivedKey) => {
  // async
});

Example 4 — Large JSON Parsing

export async function parse(req, res) {
  const data = JSON.parse(req.body.payload);
  res.json({ size: data.length });
}

Why this is a problem

  • JSON.parse is CPU-heavy for large payloads
  • blocks event loop

Fix

  • validate input size
  • limit payload size
  • avoid parsing huge objects in request path

Example 5 — Large JSON.stringify

const logs = await prisma.auditLog.findMany();
const payload = JSON.stringify(logs);
return payload;

Why this is a problem

  • large serialization blocks CPU
  • increases latency

Fix

  • paginate results
  • limit response size

How to Detect Event Loop Blocking

Look for these patterns in your code:

  • fs.readFileSync
  • crypto.*Sync
  • large loops
  • JSON.parse on large payloads
  • JSON.stringify on large arrays

Also watch for:

  • high CPU usage
  • increasing latency under load
  • inconsistent response times

These are classic signs of event loop lag.

Real Impact on Node.js Performance

Event loop blocking affects:

  • response time
  • throughput
  • system stability

Even one blocking endpoint can slow down your entire API.

That is why fixing blocking code is one of the highest-impact improvements in node js performance optimization.

How to Prevent Event Loop Blocking

The best strategy is prevention:

  • never use sync APIs in request handlers
  • keep handlers lightweight
  • limit CPU-heavy operations
  • control payload size
  • review code with performance in mind

But in real teams, mistakes still happen.

How to Catch Blocking Code Before Production

The hardest part about event loop blocking is that it often slips through code review.

It looks like:

  • "just a small helper"
  • "temporary sync call"
  • "quick loop"

But under load, it becomes a real problem.

Technical Debt Radar helps detect:

  • sync I/O in request handlers
  • CPU-heavy patterns
  • blocking operations
  • unsafe processing patterns

You can scan your project:

npx technical-debt-radar scan .

The idea is simple: catch blocking code before it hits production.

Final Thoughts

Event loop blocking is one of the simplest concepts in Node.js, but also one of the most common sources of performance issues.

The key is not just understanding it, but building habits that prevent it:

  • write non-blocking handlers
  • avoid sync operations
  • keep tasks small
  • review code with runtime behavior in mind

If you do that consistently, your Node.js applications will stay fast, even as they grow.

Detect these patterns automatically

Run one command. Get a full report in 10 seconds. No account needed.

npx technical-debt-radar scan .
Get Started Free