Skip to main content

Blocking operation

A blocking operation is a task that holds the single JavaScript thread and stops the rest of the code from running. While it lasts, the event loop waits, so the interface freezes, buttons do not respond, and animations and network requests are not processed.

Theory

TL;DR

  • JavaScript runs on a single thread; the call stack can hold only one task at a time.
  • Long synchronous code occupies the whole thread and every other task waits.
  • The event loop cannot take anything from the queue until the stack is empty.
  • setTimeout(..., 0) does not save you: the callback queues up but cannot run during the block.
  • Fixes: split heavy work into chunks, move computation into Web Workers, and in Node.js use async APIs instead of the *Sync ones.

Quick example

javascript
console.log('A'); function block(ms) { const start = Date.now(); while (Date.now() - start < ms) {} } block(3000); // block the thread for 3 seconds console.log('B');

Output:

javascript
A (pause of 3 seconds) B

While the while loop runs, JavaScript can do nothing else: no clicks are handled, no timers fire, the interface is not repainted. That is blocking.

Why it happens

JavaScript runs in a single thread: at any moment the call stack can execute only one task.

When long running code lands there, it takes the whole thread, and every other task, including asynchronous ones, waits until it finishes. Even if you have a setTimeout scheduled, it will not run until the stack is free.

Schematically:

javascript
+----------------------+ | Call Stack | <- runs the blocking operation | (busy for a long | | time) | +----------------------+ | Event loop waits Callback queue waits

No asynchronous task can enter the stack until the blocking one is done.

What happens to asynchronous code during a block

javascript
console.log('1'); setTimeout(() => console.log('2'), 0); const start = Date.now(); while (Date.now() - start < 3000) {} // blocking loop, 3 seconds console.log('3');

Output:

javascript
1 (pause of 3 seconds) 3 2

setTimeout(..., 0) did not help: its callback reached the queue but could not run until the stack was freed after the while loop.

Typical blocking operations

OperationWhy it blocks
A long while / forkeeps the CPU busy
Heavy computation (recursion, sorting, cryptography)blocks the thread
alert(), prompt()halt script execution
sync versions of Node.js methods (fs.readFileSync)wait for the result
Long JSON conversions (JSON.stringify(hugeObject))run synchronously

How to avoid blocking

Split large tasks into chunks (with setTimeout or requestIdleCallback):

javascript
function bigTask() { for (let i = 0; i < 1e9; i++) { if (i % 1e6 === 0) console.log(i); } } setTimeout(bigTask, 0); // scheduled asynchronously, does not block the interface

Use Web Workers for heavy computation on a separate thread:

javascript
// worker.js onmessage = (e) => { const result = e.data ** 2; postMessage(result); };

In Node.js, use fs.promises instead of fs.readFileSync.

Summary

Imagine you have a single waiter (the JavaScript thread):

  • Blocking code: the waiter stands at the stove waiting for a dish to cook and serves nobody else.
  • Non blocking code: the waiter passes the order to the kitchen and moves to the next table.

JavaScript behaves like the second option. But if the waiter starts stirring the soup himself for ten minutes (CPU heavy code), service stops.

TermWhat it means
Blocking operationa task that stops the rest of the code from running
Resultthe event loop freezes, the interface stops responding
Exampleslong loops, sync functions, alert(), heavy computation
How to avoid itasynchronous APIs, Web Workers, splitting the task

Common mistakes

  • Believing setTimeout(fn, 0) makes the code asynchronous "inside": it only defers the call, the function itself still blocks the thread.
  • Using fs.readFileSync inside an HTTP handler: one slow disk read stalls every request being served.
  • Serializing a huge object with JSON.stringify on the main thread instead of streaming it or moving it to a worker.
  • Confusing "a slow server request" with blocking: waiting on the network does not block the thread, computation does.
  • Thinking await frees the thread from heavy synchronous code inside the function: after the await, the code still runs on the main thread.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.