Glossary Term

How We Measure Input Lag

We sample the elapsed time between successive controller input events using performance.now() inside a requestAnimationFrame loop, over a 10-second active window with at least 30 valid samples. The result reports polling-loop latency — how quickly the browser observes state changes — not thumb-to-photon end-to-end input lag.

Definition

What How We Measure Input Lag means

How We Measure Input Lag: Our input lag methodology measures the mean inter-event delta between controller state changes reported to the browser via the Gamepad API, averaged across a 10-second active sampling window.
Also known ascontroller latency methodologyinput latency measurementpolling-loop latency
Mechanism

The exact measurement algorithm

Everything below reflects the shipped code in the browser tester. No black box — the source is open, the constants are documented, and every threshold has a specific rationale rather than being marketing round numbers.

  1. 01

    requestAnimationFrame polling loop

    The tester runs a continuous polling loop tied to the display's refresh cycle via requestAnimationFrame. On each frame, it reads the current Gamepad snapshot with navigator.getGamepads(), compares each axis and button against the previous frame's values, and records a timestamp with performance.now() the moment any input change is detected.

  2. 02

    Change detection thresholds

    A change qualifies as an event when any axis moves by more than 0.02 in absolute value from the previous reading, or when any button's pressed state flips. The 0.02 axis threshold filters out sensor noise on centered sticks; without it, drift-prone controllers would generate false events every frame and skew the result artificially low.

  3. 03

    Inter-event delta capture

    When a change fires, the tester records delta = performance.now() - timeOfPreviousChange. That delta is the interval the browser took to observe the next distinct input from the controller. Deltas above 500ms are dropped as outliers — those represent pauses between input bursts, not measurement latency.

  4. 04

    10-second sample window

    The active window runs for exactly 10,000ms after the user presses start. During that window, users are instructed to continuously rotate both sticks and tap buttons — the goal is a dense stream of state changes so we have enough deltas to statistically characterize the controller's real behavior.

  5. 05

    Aggregate metrics

    At window close, we require at least 30 valid deltas to report a result. From those we compute min, mean, 95th percentile, and max, plus a 12-bucket histogram of the full distribution. The mean is what gets graded against the threshold table; the histogram surfaces bimodal or jittery behavior that a single average would hide.

Reference

How We Measure Input Lag reported latency thresholds

The verdict bands below correspond to the same thresholds used in the tester's result panel and in the Controller Health Score latency stage. They're calibrated against the polling-loop measurement, not against hardware-instrumented end-to-end latency — a controller reporting 4ms here is not equivalent to a 4ms wired-USB gaming mouse.

Mean inter-event deltaVerdictMeaning
< 5msExcellentTournament-grade polling response. Equivalent to wired competitive controllers on modern browsers. Full 150 points in the Controller Health Score latency stage.
5–10msGoodTypical for wired controllers and high-quality wireless dongles. Imperceptible in normal play. Falls in the 90% health-score bucket.
10–20msAcceptableNormal Bluetooth range. Fine for most games; competitive FPS players may notice. Falls in the partial-severity bucket for scoring.
20–40msDegradedDetectable lag. Investigate wireless interference, low battery, or distance from receiver before assuming controller hardware failure.
≥ 40msProblematicSignificant lag. Switch to wired, change connection mode, or check for controller firmware issues. Scores zero in the latency stage.

Thresholds are hardcoded as T_EXCELLENT=5, T_GOOD=10, T_ACCEPTABLE=20, T_DEGRADED=40 in LatencyTester.tsx and mirrored by scoreLatency() in scoring/index.ts. Both files are the source of truth if there's any doubt.

See also

Related glossary terms

Frequently Asked

How We Measure Input Lag questions

No, and this distinction matters. Our measurement captures the polling-loop delta — how quickly the browser observes changes to the controller's reported state through the Gamepad API. That's the sum of the controller's own sample rate, the wireless or USB transmission time, the OS input driver, and the browser's polling interval. It does not include display latency or any latency introduced by the game engine downstream. Hardware-instrumented tools like RTINGS or DisplayLag measure something different and their numbers are not directly comparable to ours.

Two reasons. First, that equipment costs $500+ and requires a physical setup on every controller — not feasible for a browser-based tool anyone can use in ten seconds. Second, hardware-instrumented tests measure a fundamentally different quantity (thumb-to-photon) that includes display latency, which varies by monitor. Our measurement isolates a component of the input chain — the polling-loop delta — that is comparable across sessions and controllers on the same host machine. Different tool, different job.

The 10-second window balances two competing needs. Long enough to gather 200-500 valid deltas on a controller being actively worked (dense input yields dense samples); short enough that users will actually complete the test without getting bored and stopping early. In testing, extending the window to 30 seconds changed the reported mean by less than 5% on stable controllers — the sample size is already large enough for statistical significance at 10 seconds.

Below 30 samples, the standard error of the mean is large enough that reporting a specific latency number would be misleading precision. If the tester ends the window with under 30 valid deltas, it silently discards the run and returns the user to a ready state — a signal to redo the test with more continuous input. This threshold matches the sampleCount < 30 check in scoreLatency() from the Controller Health Score scoring library.

The Gamepad API reports floating-point axis values that fluctuate slightly frame-to-frame even on a stationary stick. A threshold of 0 or 0.001 would generate hundreds of false events per second on any controller with even minor drift, producing an artificially low reported latency that measures noise instead of input. The 0.02 threshold is empirically tuned to filter out sensor jitter on all major controllers we've tested while remaining sensitive enough to catch deliberate stick movement.

A delta over 500ms almost always represents a pause in user input — someone stopped moving, then started again — rather than measurement latency. Including those in the average would push the reported number up dramatically based on how consistently the user provided input, not on how the controller performs. The 500ms cutoff is well above any realistic input lag on any controller (a Bluetooth controller with 100ms latency reports deltas around 100ms, not 500ms), so we're not cutting off real data.

First-party controller specs typically don't publish end-to-end latency numbers, and when they do (for example, DualSense Edge marketing on wired-mode latency), those numbers are measured with proprietary hardware setups that aren't directly comparable to our browser-based measurement. We recommend using our numbers to compare controllers against each other on the same host, not against manufacturer specs. A DualSense measuring 8ms here versus an Xbox controller measuring 6ms is a real relative difference; both being lower than a manufacturer-published 4ms wired spec doesn't mean either measurement is wrong.

Yes — this is the most important caveat. Chrome, Firefox, and Safari all throttle background tabs' requestAnimationFrame callbacks to 1fps or lower. Running the test in a background tab will produce meaningless results. The tester requires an active, foreground tab. We do not currently gate the test on document visibility, but adding that check is on the polish backlog. In the meantime, run the test on the active tab and don't switch tabs during the 10-second window.

Written by
Abdul Soomro
Founder & Lead Diagnostic Engineer
Last reviewed
Published