The general approach
Everything on this site runs on standard browser input events. When you click, scroll, or move the mouse, the browser hands the page an event carrying a high-resolution timestamp. Precise timing of those events reveals a great deal about the hardware producing them, because mechanical faults have timing signatures that human input cannot reproduce.
Two implementation decisions matter for accuracy, and we mention them because they are where most browser-based tools go wrong:
- Sample handling never goes through a UI framework. At 1000 Hz input rates, routing every sample through component state causes dropped frames and distorted timings. Values are written directly to the page and flushed once per animation frame.
- Buffers are preallocated. Garbage collection pausing mid-measurement would add milliseconds to whichever sample it interrupted. We avoid allocating during a run.
Thresholds we use, and why
| Test | Threshold | Justification |
|---|---|---|
| Double click — chatter | gap < 30 ms | Fastest recorded human release-to-press intervals sit around 60 ms. We set the bar at half that, so no human input can trigger a false positive. |
| Double click — bounce | hold < 12 ms | Deliberate presses hold for 40 ms or more. A press this short is the contact flickering rather than a finger. |
| Scroll — stroke split | gap > 220 ms | The natural pause as a finger lifts and repositions between flicks of the wheel. |
| Scroll — minimum stroke | 3 events | Below this there is not enough signal to establish a direction, so the stroke is discarded rather than judged. |
| CPS — impossible interval | gap < 25 ms | Below the physical floor for deliberate finger cycling. Clicks this close together are switch bounce. |
| Keyboard — chatter | gap < 22 ms | Key switches have shorter travel than mouse switches, so the human floor is slightly lower. |
| Polling — valid interval | 0.05–100 ms | Anything outside this range is a duplicate timestamp or a pause in movement, not a report interval. |
Stroke segmentation on the scroll test
Most scroll tests count direction changes and call that the error count, which penalises you for scrolling naturally — every time you stop scrolling down and start scrolling up, you generate a legitimate direction change.
We segment instead. Any gap longer than 220 milliseconds ends the current stroke and starts a new one. Within each stroke we determine the dominant direction from net movement, then count only events opposing their own stroke. A deliberate direction change begins a new stroke and is never counted as a fault.
What we cannot measure
This is the part other sites leave out.
Polling rate is an estimate
Browsers coalesce pointer events to the display refresh rate. A test that counts mousemove events measures your monitor, not your mouse. We use getCoalescedEvents() to read the raw samples between frames, which is substantially more
accurate — but timestamp precision is deliberately reduced by browsers as a security measure, samples
can be dropped under load, and operating system scheduling adds jitter.
Trust our reading to distinguish 125 from 500 from 1000 Hz, and to reveal instability. Do not trust it to separate 4000 Hz from 8000 Hz. For an exact figure, read it from vendor software that queries the device directly.
Click latency is partial by definition
True end-to-end latency runs from the switch closing through USB polling, the OS input stack, the browser, rendering, compositing, and the monitor's own scan-out. JavaScript can observe only the browser and display-wait portions. We measure those precisely and say so, rather than presenting a partial number as a complete one. Use it to compare configurations on one machine, not as an absolute figure.
Firmware filtering hides early faults
Your mouse debounces contacts in firmware before reporting anything. We see what survives that filter. A switch can be degrading for months before it produces a fault visible to any browser test. A clean result means your firmware filter is coping — not that the switch is perfect. This is why we suggest re-testing periodically rather than treating one clean run as permanent.
We cannot see DPI, sensor model, or firmware
Browsers do not expose device identity for input hardware, deliberately, because it is a fingerprinting vector. Any site claiming to detect your exact mouse model in a browser is inferring it from your user agent, not reading it from the device.
Why we publish this
Utility sites in this category routinely overstate what they measure, because a confident number looks better than an honest range. We would rather be the site that hardware forums cite because the caveats are correct. If you find an error in anything here, we want to know — the about page has contact details.