A timeout delay is an eligibility threshold, not an execution deadline.
Precise claimA setTimeout delay controls when a callback may become eligible; it does not guarantee execution at that exact time, because the queued callback still needs a main-thread opportunity and the browser may add delay.
Applies
Foreground Window timers in a live browser document, demonstrated with one 600 ms callback, performance.now(), and a bounded approximately 900 ms synchronous main-thread task.
Does not prove
The page does not benchmark timer precision, promise a particular late value, reproduce background-tab throttling, cover every timer runtime, or claim that a callback can execute before the requested delay expires.
Portable rule
If an outcome depends on when a timer callback actually runs, then derive it from observed time or state instead of treating the requested delay as an execution deadline.
Declare the discussion context, then copy a stable link. No account or personal data is attached.
semantic-state puzzle
Does setTimeout(callback, 600) Run 600 ms Later?
Commit to what a 600 ms JavaScript timeout promises, measure a real callback in your browser, then keep the delay fixed while changing only main-thread availability.
The page has scheduled a real 600 ms callback. The amber marker is the requested threshold; the measured callback marker comes from this browser's monotonic clock.
Requested delay 600 msMain thread available
0600 ms requested1100 ms
Actual callback execution
Measuring…
Extra elapsed time
Pending
A setTimeout delay controls when a callback may become eligible; it does not guarantee execution at that exact time, because the queued callback still needs a main-thread opportunity and the browser may add delay.
The baseline may land close to 600 ms or noticeably later. Its exact value is not the claim; the next controlled run exposes the missing variable.
The rebuilt model
You assumed:
setTimeout(callback, 600) schedules the callback to execute exactly 600 milliseconds later.
The actual model:
The delay participates in the timer-expiry algorithm. After the waiting steps, the browser queues a task; the callback executes only when the event loop and main thread can process that task. Expiry, queueing, and execution are separate states.
The variable that failed you:
Main-thread availability after timer expiry — the callback may be eligible and queued while still unable to execute; the controlled pause is announced before it begins.
Change one variable
Keep 600 ms. Occupy the main thread.
Same requested delay, callback, clock and foreground page. This time one explicit action keeps the main thread busy for about 900 ms.
Controlled pause: running this experiment will intentionally make the page briefly unresponsive for about 0.9 seconds while synchronous work occupies the main thread.
Main-thread heartbeatready
painted ticks
The counter will run first, freeze while synchronous work owns the thread, then resume with the callback.
Reference mode skips the prediction. You can still reproduce the same fixed-delay control locally; it does not create a verdict event.
Requested delay 600 msMain thread preparing
0600 ms expires900 ms thread frees
Actual callback execution
Waiting…
After requested threshold
Pending
Your two committed modelsPending
Pending
One variable changed. The requested delay stayed fixed.
Run
Delay
Main thread
Callback
Baseline
600 ms
available
Not measured
Controlled rerun
600 ms
occupied 900 ms
Not measured
The callback was not cancelled and the 600 ms expiry did not interrupt the synchronous task. It executed only after the main thread became available.
The timer initialization algorithm waits for the requested duration, may include implementation-defined padding, and then queues a task on the timer task source rather than guaranteeing callback execution at an exact instant.
The actual delay may be longer than requested, including when currently executing code must complete before the timeout callback can run; it also documents separate throttling cases.
performance.now() exposes a monotonic time value suitable for measuring elapsed durations without wall-clock adjustments.
standard — checked 2026-07-21.
Scope: Foreground Window timers in a live browser document, demonstrated with one 600 ms callback, performance.now(), and a bounded approximately 900 ms synchronous main-thread task.
Does not prove: The page does not benchmark timer precision, promise a particular late value, reproduce background-tab throttling, cover every timer runtime, or claim that a callback can execute before the requested delay expires.
If an outcome depends on when a timer callback actually runs, then derive it from observed time or state instead of treating the requested delay as an execution deadline.
Countdowns
Compute remaining time from a monotonic start or target timestamp; do not subtract one merely because another one-second callback arrived.
Polling and backoff
Treat the delay as the earliest retry opportunity and re-check current state when the callback runs instead of assuming a precise network schedule.
Interface animation
Render from elapsed time or current state so a busy frame produces a jump to truth rather than a permanently slow clock.