Stop 05 · Backend with Node.js & ExpressTopics · 1/8

Node.js Runtime & Event Loop

Part of the Full Stack Developer Roadmap

In short

Node.js runs your JavaScript on one main thread, yet one small server can juggle thousands of users. The trick is the event loop, and one bad loop in your code can freeze everyone.

The JavaScript runtime (built on V8) that lets you run the same language you use in the browser on the server — and the event loop that lets it handle many concurrent requests despite being single-threaded.

The mascot loads paper into a busy copier while turning to serve the next customer.

Think of it like this

The one-man photocopy shop

Bhaiya puts your 200-page job on the machine and immediately serves the next customer. When the machine beeps, he hands over your copies. He never stands watching it print. But if he sits down to hand-staple 500 sheets, the whole queue waits.

Watch it happen

The callback queue in a busy API

enqueue(A: DB rows ready)
A: DB rows ready

Front of the queue is coloured

1/6Request A started a database query earlier. The rows are back, so its callback joins the queue.

The big ideas

What you need to know

V8 plus system powers

Node is Chrome's V8 engine with extra APIs for files, network and processes. No window or document here.

I/O waits off the main thread

Database calls, file reads and HTTP requests are handed off. Your thread is free to serve others meanwhile.

CPU work blocks everyone

A heavy loop, huge JSON.parse or sync crypto holds the thread. Every other request waits until it ends.

Avoid *Sync in servers

fs.readFileSync is fine in a script, but in a route handler it stalls all users. Use the promise versions.

See it in code

Walk through the code

js
1import express from "express";2import { readFile } from "node:fs/promises";3 4const app = express();5app.get("/report", async (req, res) => {6  const data = await readFile("big-report.csv", "utf8"); // waits, doesn't block7  res.send(`Lines: ${data.split("\n").length}`);8});9 10app.get("/slow", (req, res) => {11  let x = 0;12  for (let i = 0; i < 5e9; i++) x += i; // blocks EVERY request for seconds13  res.send(String(x));14});15 16app.listen(3000);

1/3await hands the file read to the system. Other requests run while the disk works.

Hit /slow in one tab and /report in another. /report waits too, because the single thread is busy counting.

Save yourself the pain

Common mistakes

Oops

Thinking 'single-threaded' means Node can only serve one user at a time.

Do this instead

It runs one piece of JavaScript at a time, but thousands of requests can be waiting on I/O together.

Oops

Resizing images or hashing big files directly inside a route handler.

Do this instead

Move heavy CPU work to a worker thread or a background job queue so the API stays responsive.

Your mission

Freeze your own server

~20 min

Quick check

Two users hit your API at once. One request awaits a 300 ms database query. What happens to the other request meanwhile?

Go deeper

  1. 1Install Node.js and run a simple script from the command line.
  2. 2Log the order of `setTimeout`, `Promise.then` and synchronous code to see the event loop in action.
  3. 3Understand why a long synchronous computation blocks the entire server.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge