# Gamepad Tester

> Test any controller in your browser: live button and trigger view, analog-stick drift measurement, dead zones, vibration test and polling rate. Free online.

- URL: https://bytescope.dev/en/gamepad-test/
- Locale: en · Also: [ja](https://bytescope.dev/ja/gamepad-test.md) · [zh-Hant](https://bytescope.dev/zh-Hant/gamepad-test.md)
- Runs: Everything runs locally in your browser — nothing is uploaded.
- Requires: Any modern browser (Chrome, Edge, Firefox, Safari), desktop and mobile.
- Updated: 2026-09-08

## What it does

Connect a controller over USB or Bluetooth and press any button to wake it (the Gamepad API only reveals a pad after input — the page guides you through this). Every button lights up on a controller diagram as you press it, triggers show their analog 0–1 values, and multiple controllers can be tested side by side.

The stick analysis is the heart of the tool. A live XY scatter plot with trail shows exactly where each stick sits; a circularity test has you roll the stick around its rim to reveal range problems; a magnified center view makes resting offset visible; and the guided drift test — hands off the controller for 10 seconds — measures average and peak deviation and gives a plain verdict like "left stick drifts 3.2%, above the normal range". Stick drift is the defining fault of modern controllers, and measuring it beats guessing.

Rounding it out: a dual-rumble vibration test with separate strong/weak motor sliders, a polling-rate estimate from timestamp deltas (125 Hz wired pads vs 1000 Hz esports pads show up clearly), and the same rapid re-trigger chatter detection used in our keyboard tester. Everything runs locally in your browser — input data never leaves your device.

Three power-user extras round out the workbench. An input-latency test flashes a prompt and times your press two ways at once: a reaction figure (flash-to-press, which honestly includes your own reaction time) and a pipeline figure that removes human reaction by differencing the Gamepad API's own timestamp against the frame it first becomes readable — the closest a sandboxed page can get to device-plus-polling latency. With two controllers connected, a side-by-side compare mode puts both diagrams and stick scatters in one view, so a known-good pad reads directly against a suspected-drifting one. And an export button downloads the full diagnostic as JSON — id, mapping, button and axis counts, current values and observed min/max ranges, the polling-rate estimate and any drift results — ready to attach to a warranty claim or forum post.

## Limits

Does not remap buttons, update firmware or fix drift; it shows live Gamepad API input.

## Machine output

Copy JSON copies an envelope `{ tool, url, generatedAt, userAgentHint, result }`. `tool` is `"gamepad-test"`; `result` is per-pad button/axis aggregates. An unpressed button is never reported as unresponsive.

- `gamepadApiPresent` (boolean | null) — `null` = not probed yet; `false` = probed, `navigator.getGamepads` missing; `true` = API present.
- `connectedCount` (number) — How many pads are listed in `pads`.
- `pads` (array of objects) — Connected pads, sorted by `index`. Each pad: index, id, mapping, buttonCount, axisCount; `pressedButtonIndexes` / `notPressedButtonIndexes` / `movedAxisIndexes` (sorted number[] or `null` when this pad was not the selected readout — not observed; `[]` means observed, none); `unresponsiveButtonIndexes` (always `null` — this page has no dead-button confirmation); `axisMovedThreshold` (number or `null` when not observed); `axisObservedRanges` (per-axis max−min, or `null` on the whole field if not observed; unobserved axes inside the array are `null`); `vibrationActuatorPresent` (boolean or `null` when not the selected pad / not probed); `measuredPollHz` (number or `null` when not enough timestamp deltas); `snappedPollHz` (number or `null` when nothing nearby); `pollRateIsLowerBound` (`null` = poll rate not measured; `true` = timestamps look quantized so `measuredPollHz` is a lower bound; `false` = measured, not flagged as quantized).

## FAQ

### My controller doesn't show up — what do I do?

Press any button on it first: browsers hide gamepads until they receive input, as a privacy measure. If it still doesn't appear, check that it's paired/connected at the OS level, and try another USB port or re-pairing Bluetooth. Some very old or exotic pads don't implement the standard mapping and may appear with unusual button numbering.

### How much stick drift is normal?

At rest, a healthy stick should sit within about 1–2% of center (games hide this inside their dead zones, typically 5–10%). Consistent resting offset beyond ~3–5%, or a stick that wanders while untouched, will be visible in gameplay as unwanted movement — that's the classic worn-potentiometer fault that warrants cleaning, recalibration or repair.

### Does the vibration test work with every controller?

It uses the Gamepad API's dual-rumble actuator, which works for most Xbox and PlayStation pads in Chromium browsers. Some browsers and some pads (and most Bluetooth connections on macOS) don't expose rumble — the tool tells you when the actuator isn't available rather than failing silently.

### Can I use a Switch Pro controller or Joy-Cons?

Yes for testing: they pair over Bluetooth and expose the standard mapping in most browsers. Note the browser can only read the controller — it cannot turn it into a system-wide virtual gamepad for other PC games; that requires a driver-level tool like BetterJoy or Steam Input.

### What does the polling rate number mean?

How often your controller reports its state, estimated from the timestamps between updates. 125 Hz (8 ms) is the common baseline, high-end wired pads reach 1000 Hz (1 ms). Lower isn't broken — but if a "1000 Hz" pad measures 125 Hz, check its wired connection and mode.

### How accurate is the input-latency test?

It reports two numbers. The reaction figure (green flash to button press) is dominated by your own reaction time — useful for comparing setups, not for judging a controller. The pipeline figure is more honest about hardware: it measures how stale the pad's state is when a requestAnimationFrame loop can first act on it, by differencing the Gamepad API's timestamp against the frame time. A browser sandbox can't measure true end-to-end display latency, and timestamp granularity plus your polling interval put a floor under the pipeline number, so read it as an upper bound on input freshness rather than a lab-grade figure.

### Can I compare two controllers at once?

Yes — connect two pads and switch to Compare mode. Each controller gets its own live diagram and stick scatter/drift readout side by side, which is the fastest way to see a worn stick against a healthy one. You choose which two of the connected pads sit in each column.

### What's in the exported JSON?

The selected pad's id, standard-mapping name, button and axis counts, each control's current value plus the minimum and maximum observed while you were testing, the polling-rate estimate, and the drift-test results if you ran them. Everything is generated in your browser and downloaded directly — nothing is sent anywhere. Roll every stick around its rim and squeeze both triggers before exporting so the observed ranges are complete.
