Skip to content

The Call Stack

The call stack is a LIFO (Last In, First Out) data structure that tracks the currently executing functions. Every time a function is called, a new frame is pushed onto the stack. When the function returns, its frame is popped off.

function greet(name) {
return 'Hello, ' + name;
}
function main() {
var msg = greet('Node');
console.log(msg);
}
main();
// Stack at peak: [main] → [main, greet]
// After greet returns: [main]
// After main returns: []

The engine can only execute one frame at a time. While a frame is executing, nothing else can run — no I/O callbacks, no timer callbacks, nothing.

All synchronous code runs to completion before anything in the async queues can execute. Consider a countdown:

function countdown(n) {
if (n <= 0) {
console.log('done');
return;
}
console.log(n);
countdown(n - 1);
}
countdown(5);

Each recursive call pushes a new frame. The output is completely deterministic: 5, 4, 3, 2, 1, done.

Run it:

JavaScript

If you run a long synchronous operation — a heavy computation, a large loop, a synchronous file read — the call stack is occupied for the entire duration. No other code can run until the stack clears.

// This blocks for ~200ms — nothing else can happen during this time
var start = Date.now();
while (Date.now() - start < 200) {
// spinning
}
console.log('Finally unblocked');

In a server, this means every incoming request waits during that block. Keep synchronous work short.

What data structure describes how the call stack processes function calls?
What happens to a setTimeout callback while a long synchronous loop is running?
When does a function frame get removed from the call stack?