October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk4 min

JavaScript Countdown Timers: Why setInterval Drifts and How to Fix It

A reliable JavaScript countdown derives remaining time from a stored start time or deadline—not from how many setInterval callbacks have run.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

setInterval(..., 1000) does not guarantee a callback every second. A countdown that subtracts one second each time the callback runs measures callback count, not elapsed time. If JavaScript is busy or the browser throttles timers in a background tab, callbacks arrive late and the displayed countdown falls behind. Keep a clock-based start time or deadline as the source of truth, then calculate the remaining time afresh on each update.

Why does setInterval drift?

A timer delay is a scheduling request, not a promise of exact callback spacing. MDN Web Docs puts it plainly: “Note also that the actual amount of time that elapses between calls to the callback may be longer than the given delay.” (MDN: Window.setInterval())

As an Amazon Associate I earn from qualifying purchases.

Timer callbacks run through the event loop. They cannot interrupt JavaScript already running on the main thread, so a busy page can delay a callback. Browsers can also throttle timers in inactive tabs, according to browser-specific rules. (MDN: Window.setTimeout())

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If each delayed callback still subtracts exactly one second, every delay becomes permanent error in the counter. Requesting a shorter interval does not solve the underlying problem: the browser can still delay scheduling or execution. There is no general measured drift figure in the cited API documentation, and actual delays depend on runtime conditions.

Make the clock or deadline the source of truth

Instead of decrementing a variable, record a start time or target deadline. On each render, find the difference between that time and the current time. A late callback may make the display update late, but the next calculation reflects elapsed time rather than pretending only one interval passed.

Countdown for a duration in the current page

Use performance.now() to measure elapsed duration within the page’s time origin. It is monotonic, so system clock adjustments do not change the elapsed-time calculation. It is relative to performance.timeOrigin, not Unix epoch time. (MDN: Performance.now(); MDN: High precision timing)

const durationMs = 60_000;
const startedAt = performance.now();

function render() {
  const elapsed = performance.now() - startedAt;
  const remainingMs = Math.max(0, durationMs - elapsed);
  showRemaining(remainingMs);

  if (remainingMs > 0) {
    setTimeout(render, 100); // Display cadence only; elapsed time is recomputed.
  }
}

render();

The 100 ms timeout above controls how often the display is refreshed; it does not define the countdown’s accuracy. The code examples here illustrate the timing pattern and are not reported test results. MDN notes that whether performance.now() advances during system sleep can vary by operating system, so decide whether sleep should count for your application and reconcile on resume if needed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Countdown to a persistent deadline

If a target must survive a reload or be compared with an epoch-based timestamp, store an epoch deadline using Date.now() and recompute the remainder from it:

const durationMs = 60_000;
const deadline = Date.now() + durationMs;

function render() {
  const remainingMs = Math.max(0, deadline - Date.now());
  showRemaining(remainingMs);

  if (remainingMs > 0) {
    setTimeout(render, 100);
  }
}

render();

Date.now() uses wall-clock time, so a user or system clock change can affect the result. Choose it when an epoch-based deadline is needed, and account for clock changes when they matter. Do not subtract a performance.now() value from a Date.now() value directly: they belong to different clock domains.

What to do when the page returns to the foreground

When a hidden page becomes visible again, immediately recalculate from the stored start time or deadline and repaint. Do not replay one callback for every missed second: those callbacks did not measure the time that passed. The Page Visibility API can notify the application when visibility changes; the exact background throttling policy varies by browser. (MDN: Page Visibility API)

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Choose a scheduler for the display or work

Need Suitable scheduler What it does not guarantee
Simple countdown display setInterval or recursive setTimeout Exact callback timing; derive remaining time from a clock or deadline.
Work that must not overlap itself Recursive setTimeout Fixed-rate execution; the next call is scheduled after the previous work completes.
Smooth visual animation requestAnimationFrame Background execution; most browsers pause it for hidden pages.
Work in a worker context Worker timers A universal exact-time guarantee; timer constraints still apply.

Recursive setTimeout is useful when a cycle’s work may take longer than the requested delay: scheduling the next cycle after the current work finishes avoids overlapping cycles. It still does not create a precise clock. (MDN: Window.setInterval())

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

requestAnimationFrame is a one-shot callback generally aligned with the browser’s painting schedule, making it suitable for visual animation. Most browsers pause it in background tabs. It schedules presentation; it does not make a deadline-based countdown accurate by itself. (MDN: Window.requestAnimationFrame())

A worker can move work away from window main-thread tasks, but it does not guarantee exact timing or remove browser lifecycle constraints. A visible countdown still needs its interface updated. (MDN: WorkerGlobalScope.setInterval())

Common countdown-timer mistakes

  • Subtracting a fixed amount per callback: A callback can arrive late, so callback count is not elapsed time.
  • Using a smaller interval to chase accuracy: Shorter requested delays do not prevent main-thread contention or background throttling.
  • Treating recursive setTimeout as a precision clock: It prevents the next cycle from being scheduled before the previous one finishes, but its delay is still a scheduling request.
  • Relying on requestAnimationFrame for background ticking: Most browsers pause it in hidden pages.
  • Mixing clock domains: performance.now() is time-origin-relative, while Date.now() is epoch-based and can reflect system clock changes.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.