Node.js Runtime Internals
Track #4 of the study plan. How Node.js actually runs your code under the hood.
Event Loop (libuv)
Phases in order, per iteration (tick):
- timers — callbacks of
setTimeout/setInterval. - pending callbacks — some deferred I/O callbacks.
- idle/prepare — internal.
- poll — fetches new I/O events; runs I/O callbacks.
- check —
setImmediatecallbacks. - close callbacks — e.g.
socket.on('close').
- Microtasks run between phases and fully drain:
process.nextTick(own queue, top priority) and then Promises (then/catch/finally). setImmediate(check) vssetTimeout(0)(timers): the order depends on context; inside an I/O callback,setImmediateruns first.
console.log("1");
setTimeout(() => console.log("timeout"), 0);
setImmediate(() => console.log("immediate"));
Promise.resolve().then(() => console.log("promise"));
process.nextTick(() => console.log("nextTick"));
console.log("2");
// 1, 2, nextTick, promise, (timeout/immediate depending on context)
libuv & thread pool
- Node is single-threaded for JS, but libuv uses a thread pool
(default 4,
UV_THREADPOOL_SIZE) for: fs, DNS (dns.lookup),crypto.pbkdf2,zlib. - Blocking the event loop (heavy CPU loop,
*Sync) freezes all connections. Offload toworker_threadsor a queue (see nodejs-high-concurrency).
V8
- Call stack + heap; generational GC (new space / old space), scavenge vs mark-sweep-compact.
- Hidden classes / inline caches — keeping object shape stable helps the JIT.
- Useful flags:
--max-old-space-size,--inspect(DevTools), heap snapshots.
Streams & backpressure
Readable/Writable/Transform/Duplex;pipe/pipeline.- Backpressure:
write()returnsfalse→ stop until thedrainevent. - Use streams for large files/responses to avoid blowing up memory.
Concurrency & processes
worker_threads— CPU parallelism, shareable memory (SharedArrayBuffer).cluster/ PM2 — multiple processes sharing a port (scales over cores).child_process— spawning external processes.
Memory diagnostics
- Common leaks: unremoved listeners, closures holding refs, unbounded caches, orphan timers.
- Tools:
--inspect+ Chrome DevTools, heap snapshots,clinic.js,--prof.
Interview questions (practice)
- Explain the event loop phases. Where do microtasks fit in?
process.nextTickvssetImmediatevssetTimeout(0)?- What does the libuv thread pool process?
- What happens if you block the event loop? How do you avoid it?
- What is backpressure in streams?
Related: nodejs-high-concurrency · express-middleware-chain · study plan.