setTimeout with Zero Delay Explained
setTimeout(cb, 0) does not run immediately. Here is why and what it is actually useful for.
setTimeout with Zero Delay Explained
setTimeout(callback, 0) is a common pattern, but it does not run the callback immediately. Here is why and what it is actually useful for.
What setTimeout(cb, 0) Does
setTimeout(() => console.log("later"), 0); console.log("now"); `` **Output**: `now, later`. 1. The timer is set to 0ms. 2. The callback is pushed to the **macrotask queue**. 3. Synchronous code continues (`console.log("now")` runs). 4. After the stack is empty and microtasks are done, the event loop moves the callback to the stack. 5. `"later"` is logged. ### Why It Does Not Run Immediately `setTimeout` always goes through the Web API and the macrotask queue. The event loop only runs macrotasks when the call stack is empty. Even with 0 delay, the callback waits for the current synchronous code to finish. ### Microtasks Run First ```js setTimeout(() => console.log("timeout"), 0); Promise.resolve().then(() => console.log("promise")); `` **Output**: `promise, timeout`. The promise callback (microtask) runs before the timer callback (macrotask). ### What `setTimeout(cb, 0)` Is Useful For #### 1. Deferring Work to Keep the UI Responsive ```js function defer(fn) { setTimeout(fn, 0); } // lets the browser render between chunks of work `` #### 2. Breaking Long Tasks Into Chunks ```js function chunkedProcess(items) { let i = 0; function chunk() { const end = Math.min(i + 100, items.length); for (; i < end; i++) { process(items[i]); } if (i < items.length) setTimeout(chunk, 0); } chunk(); } `` #### 3. Allowing the Browser to Paint ```js // update the UI before a long task statusElement.textContent = "Loading..."; setTimeout(() => { doHeavyWork(); }, 0); `` Without the `setTimeout`, the browser might not paint "Loading..." before `doHeavyWork` blocks the thread. ### Browser Throttling Browsers may throttle `setTimeout(cb, 0)` to a minimum of 4ms after 5 nested levels. In background tabs, timers are often throttled to 1 second minimum. This is to prevent abuse. ### Better Alternatives - **`queueMicrotask(fn)`**: runs `fn` as a microtask (before the next macrotask). Faster than `setTimeout(cb, 0)`. - **`requestAnimationFrame(fn)`**: runs `fn` before the next paint. Best for visual updates. - **`requestIdleCallback(fn)`**: runs `fn` when the browser is idle. Best for low-priority work. ### The Takeaway `setTimeout(cb, 0)` does not run immediately. It goes to the macrotask queue and runs after the stack is empty and microtasks are done. It is useful for deferring work, breaking long tasks, and allowing the browser to paint. For better alternatives, use `queueMicrotask`, `requestAnimationFrame`, or `requestIdleCallback`.
No. The callback goes to the macrotask queue. The event loop runs it only after the call stack is empty and all microtasks are done. So it runs after the current synchronous code, not immediately.
Because promise callbacks go to the microtask queue, which the event loop drains completely before touching the macrotask queue where setTimeout callbacks live. Microtasks always run before macrotasks, regardless of delay.
Deferring work to keep the UI responsive, breaking long tasks into chunks (so the browser can render between chunks), and allowing the browser to paint a UI update before a heavy task blocks the thread.
Yes. After 5 nested levels, browsers may throttle setTimeout to a minimum of 4ms. In background tabs, timers are often throttled to 1 second minimum. This prevents abuse.
queueMicrotask(fn) runs fn as a microtask (before the next macrotask). requestAnimationFrame(fn) runs fn before the next paint (best for visual updates). requestIdleCallback(fn) runs fn when the browser is idle (best for low-priority work).
Ready to master React completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master React
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

