🔧 Controls
ℹ Tips
- Start begins counting from zero or resumes from a paused value.
- Pause freezes the elapsed value without clearing laps; press Start to resume.
- Lap records the current split and the delta from the previous lap.
- Reset zeroes everything and clears every recorded lap.
⏱ Elapsed
Always HH:MM:SS.mmm. Hour padding is dropped
once the count exceeds 99 hours so very long runs render
cleanly.
🚩 Laps
- {{ 'Lap ' + row.number }}: {{ row.lapFormatted }} (split {{ row.splitFormatted }})
ℹ️ About Stopwatch
What this tool does
The Stopwatch counts up from zero with millisecond precision.
Hit Start to begin, Lap to
record a split, Pause to freeze the elapsed
value, and Reset to clear everything. The
display always shows the full HH:MM:SS.mmm form
so you can see fractional seconds at a glance. Laps are
listed newest-first with both the lap delta and the running
split for that lap.
How it works (technical details)
- Pure client-side. Elapsed time, lap math, and the rendered display are all computed inside your browser. No network request is made, and no data leaves the page.
-
Monotonic clock. The stopwatch uses
performance.now(), a high-resolution monotonic timestamp that is not affected by user-initiated wall-clock changes, NTP corrections, or daylight-saving transitions.Date.now()can jump backwards;performance.now()cannot, which is why it is the right primitive for a stopwatch. -
Per-frame update. The elapsed value is
recomputed every animation frame via
window.requestAnimationFrame. Background tabs throttle that callback, but the next visible frame still reads a fresh timestamp so the display catches up instead of drifting. -
Pause/resume math. Pause folds the
current elapsed value into an accumulated
bucket and clears the start timestamp. Start re-captures
performance.now()and the rAF loop reports(now − startedAt) + accumulatedfrom then on, so the displayed value continues from where it stopped. -
Lap math. Each lap stores the split
(total elapsed at the moment Lap was pressed) and the
lap delta (split minus the previous lap's split). The
ISO timestamp recorded with each lap is the
wall-clock instant from
Date.now(), used only as a human-readable annotation; the stopwatch arithmetic itself never touchesDate.now().
Use cases
- Workout intervals — count up through a HIIT round and record per-rep splits.
- Pair sessions and focus blocks — visible running time during a coding sprint or a meeting timebox.
- Benchmarking — quick wall-clock sanity check for a manual operation when a dedicated benchmark harness would be overkill.
- Cooking and brewing — multi-stage timing with explicit lap markers between steps.
- Race-style splits — record lap times during a run, ride, or game with newest lap shown first.
Privacy note
Every measurement, every lap, and every formatted display value lives inside this page. No elapsed time, no lap data, and no timestamps are sent to a server. There is no API endpoint for this tool — the algorithm is trivial and the interesting behavior is entirely in your browser.
References
- MDN — performance.now() — the high-resolution monotonic clock used to measure elapsed time.
- MDN — window.requestAnimationFrame — the timing primitive driving the per-frame recompute loop.
- For a countdown to a target moment, see the Countdown Timer.
- For arithmetic on
HH:MM:SSdurations, see the Time Duration Calculator.