When does setTimeout start counting down?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
setTimeout is simple on the surface, but timing behavior depends on the event loop, call stack load, and browser throttling rules. The timer does not guarantee exact execution time, only a minimum delay before callback eligibility. Understanding when countdown starts and when callback runs prevents subtle asynchronous bugs.
Core Sections
When the Countdown Starts
The setTimeout countdown starts immediately when JavaScript executes the setTimeout call. If you pass 2000, the runtime schedules callback eligibility for at least two seconds later.
Logs show A and C first because setTimeout only registers work. The callback cannot run until the current call stack is empty and the event loop reaches timer tasks.
Minimum Delay Versus Actual Execution
A timer delay is a lower bound, not a precise schedule. If the main thread is busy, callback execution can be delayed well beyond the requested value.
Even with 100 ms delay, callback runs after the blocking loop completes. This is normal event-loop behavior.
Event Loop Queue Position
Timers become queued tasks after their delay expires. They still wait behind currently running JavaScript and other queued tasks.
Output order is usually:
syncmicrotasktimeout
Microtasks run before timer tasks in the same loop turn.
Nested Timers and Clamping
Browsers apply clamping rules to repeated nested timers, often enforcing a minimum around a few milliseconds. In inactive tabs, throttling can be much stronger to save resources.
You may not get exact one millisecond intervals, especially under background tab conditions.
Measuring Real Delay
If accurate timing matters, measure actual elapsed time rather than trusting delay values.
This makes latency visible and helps diagnose blocking work or throttling.
Better Patterns for Repeated Work
For periodic tasks, setInterval can drift if callbacks take longer than interval duration. Recursive setTimeout with drift correction can be more predictable.
This keeps repeated execution closer to target cadence under light load.
Choosing Between setTimeout and requestAnimationFrame
For visual updates, requestAnimationFrame aligns callback execution with browser paint cycles and often feels smoother than timers.
Use setTimeout for generic delayed tasks and requestAnimationFrame for animation loops. Picking the right primitive reduces jitter and timing surprises in UI code.
Common Pitfalls
- Assuming timer callbacks run exactly at delay boundaries.
- Blocking the main thread and then blaming timer accuracy.
- Using
setTimeout(fn, 0)as if it runs before microtasks. - Ignoring background-tab throttling in browser timing logic.
- Using
setIntervalwithout handling callback duration and drift.
Summary
- Countdown starts when
setTimeoutis executed. - Delay is minimum wait time, not guaranteed execution timestamp.
- Callback runs only when event loop can process timer tasks.
- Main-thread blocking and browser throttling affect observed timing.
- Measure actual elapsed time for timing-sensitive features.

