Node.js Architecture
Node runs your JavaScript on a single thread, yet handles thousands of connections. The secret is the event loop: Node hands slow work to the system and gets back to your code when it is done.
On this page · 5 min · Beginner
On this page
- Learning objectives
- Explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Beginner
- Updated
- Oct 28, 2026
Related tutorials
Learning objectives#
- Describe V8, libuv and the event loop
- Predict the order of sync code, microtasks and timers
- Explain non-blocking I/O
- Recognise and avoid blocking the event loop
Explanation#
V8 executes your JavaScript. libuv provides the event loop and asynchronous I/O (network, files, timers), using the operating system and a small thread pool.
Your code runs on one main thread with a call stack. When you start I/O (read a file, query a database), Node registers a callback and moves on.
When the I/O finishes, its callback is queued. The event loop picks queued callbacks one at a time whenever the call stack is empty.
Order: synchronous code first, then microtasks (resolved promises; process.nextTick is a similar high-priority queue), then macrotasks like timers and I/O callbacks.
Blocking code (a long loop, readFileSync on a big file, heavy JSON.parse) keeps the stack busy, so no other callback — no other user — can run. Keep handlers short and async.
Syntax#
your code ──► call stack (V8, single thread)
│ async work (fs, net, timers)
▼
libuv ── OS / thread pool ── done ──► callback queue ──► event loop ──► call stack
Code example: Predict the order of execution#
console.log('1. start');
setTimeout(() => console.log('5. timeout (macrotask)'), 0);
Promise.resolve().then(() => console.log('4. promise (microtask)'));
console.log('2. end of synchronous code');
// A blocking loop delays everything that is waiting
const start = Date.now();
while (Date.now() - start < 200) { /* busy for 200 ms */ }
console.log('3. after 200 ms of blocking work');
1. start 2. end of synchronous code 3. after 200 ms of blocking work 4. promise (microtask) 5. timeout (macrotask)
This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- All synchronous lines run first, top to bottom — including the 200 ms busy loop.
- Only when the call stack is empty does Node process queued work.
- The promise callback (a microtask) runs before any timer.
- The timeout callback runs last, even with a 0 ms delay — and it waited the full 200 ms of blocking.
Real-world use case#
An API got slow for everyone whenever one user downloaded a report: the report was built with a synchronous loop over 200,000 rows. Moving it to a worker thread kept the event loop free and response times flat.
Common mistakes#
It runs after the current code and all microtasks finish.
fs.readFileSync, crypto.pbkdf2Sync and big loops block every request. Use the async versions.
Your JS runs on one thread, but I/O happens in parallel in the OS and thread pool; worker_threads add CPU parallelism.
Best practices#
- Never block the event loop in request handlers
- Prefer async APIs everywhere
- Move CPU-heavy tasks to worker threads or queues
- Measure event-loop delay in production
Remember this#
One JS thread + event loop + libuv for I/O.
Order: sync code → microtasks (promises) → timers/I/O.
Blocking the loop blocks every user.
Practice exercise#
Your task: Predict the output order: console.log("A"); setTimeout(() => console.log("B")); Promise.resolve().then(() => console.log("C")); console.log("D");
Need a hint?
Show solution
console.log('A');
setTimeout(() => console.log('B'));
Promise.resolve().then(() => console.log('C'));
console.log('D');
// A
// D
// C
// B
Mini quiz#
What is the output order?
setTimeout(() => console.log('T'), 0);
Promise.resolve().then(() => console.log('P'));
console.log('S');
Want more? Practise all Node.js MCQs · Node.js interview questions
My notes#
Saved in this browser.