Concurrency & the event loop
Part of the Backend Developer Roadmap
In short
"What does this code print?" with setTimeout and Promises is a Node.js interview favourite. Understand the event loop and you can answer it, and avoid blocking your server.
Deep understanding of how Node.js handles concurrency despite being single-threaded — a frequent, somewhat tricky interview topic that trips up candidates who've only used async/await without understanding it.

Think of it like this
One waiter at a busy dhaba
He takes an order, passes it to the kitchen and moves to the next table instead of standing there. When a dish is ready, he delivers it. One waiter serves twenty tables. If he starts cooking himself, everyone waits.
Watch it happen
Why A, D, C, B?
log("A")
1/6Plain code runs first, top to bottom. A prints.
The big ideas
What you need to know
One thread runs your JS
The event loop picks the next callback when the stack is empty. Slow I/O happens outside, in libuv and the OS.
Microtasks jump the queue
Promise callbacks run right after the current code, before timers or I/O callbacks.
Never block the loop
A long CPU loop or a sync function like fs.readFileSync in a hot path stalls every request. Use worker_threads or a queue.
Races still happen
Between two awaits, other requests run. "Check then update" logic needs atomic database operations or locks.
See it in code
Walk through the code
1console.log("A");2setTimeout(() => console.log("B"), 0);3Promise.resolve().then(() => console.log("C"));4console.log("D");5// Output: A, D, C, B6 7// Blocking: nothing else runs while this loop spins8app.get("/report", (req, res) => {9 let total = 0;10 for (let i = 0; i < 5e9; i++) total += i; // every other request waits11 res.json({ total });12});13// Fix: move CPU-heavy work to worker_threads or a job queue1/3Synchronous logs first, then microtasks, then timers.
While /report is computing, even a simple health check can't respond. Many unexplained timeouts in production are this.
Save yourself the pain
Common mistakes
Oops
Saying async/await makes code run in parallel threads.
Do this instead
await just pauses that function and frees the thread. The work runs concurrently, not in parallel.
Oops
Assuming two requests can't interfere because Node is single-threaded.
Do this instead
They interleave at every await. Read-modify-write on shared data still needs atomic updates.
Your mission
Predict, then run
Quick check
What does this print? console.log(1); setTimeout(() => console.log(2), 0); Promise.resolve().then(() => console.log(3)); console.log(4);
Go deeper
- 1Practice explaining the event loop phases and the microtask/macrotask queue distinction.
- 2Be ready to predict the output order of a tricky async code snippet.
- 3Understand what actually blocks the event loop and what doesn't.
More technical 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.