Web MIDI Keyboard Latency Tester

Dead keys, ghost notes, and USB-to-browser latency — all analysis runs locally. No data transmitted.

ZERO UPLOAD · ALL LOCAL
  1. Connect your MIDI keyboard via USB. Chrome, Edge, and Opera are required — Firefox and Safari do not support Web MIDI.
  2. Click "Enable MIDI" and allow MIDI device access in the browser prompt.
  3. Select your keyboard from the "MIDI Input" dropdown if multiple devices are connected.
  4. Press each key across the full range — any key that does not light up on the virtual piano is a dead key.
  5. Check the event log for "⚠ GHOST" markers — these flag duplicate Note On events within 30 ms of each other.
  6. Review the "Lag" column in the event log to see USB-to-browser latency per key press.
  7. Click "Clear Log" to reset the event log before testing a new section of keys.

What the API can and can't do

  • Standard messages Note On/Off, CC, pitch bend, aftertouch, program change — read and write
  • SysEx requires a separate sysex: true permission flag
  • Supported browsers Chrome, Edge, Opera; Firefox is add-on gated; Safari unsupported
  • Transport limits reads through the OS MIDI subsystem — no direct access to MIDI DIN ports

Velocity at a glance

  • 0–127, 7-bit integer
  • treated as Note Off by most synthesizers
  • time between two contacts closing, not force
  • expanded to 16-bit (0–65535)

A gentle but fast press can register high velocity, while a slow, hard press can still read low — velocity times a strike, it doesn't weigh it.

Channel facts worth knowing

  • Total channels 16 per MIDI connection, numbered 1–16 (encoded 0–15)
  • Channel 10 reserved for percussion under General MIDI
  • GM drum mapping example note 36 = Electric Bass Drum, note 38 = Acoustic Snare, note 42 = Closed Hi-Hat
  • Omni mode a synth responds to all 16 channels at once, ignoring the channel number

Standard CC number table

  • Modulation wheel
  • Channel volume
  • Pan
  • Expression
  • Damper (sustain) pedal
  • Reverb send / Chorus send

Numbers 0–31 are MSB controllers; 32–63 are their LSB counterparts for 14-bit precision.

MIDI device access is required to run any test. Access is only used for analysis — no MIDI data is transmitted.

Connecting to MIDI…

The Web MIDI API is not available in this browser. Chrome 43+, Edge 79+, Opera 30+, and Firefox 108+ support Web MIDI.

Safari does not support Web MIDI. Switch to Chrome, Edge, Opera, or Firefox 108+ and reload this page.

MIDI access was blocked. To allow it:

  1. Click the lock icon in your browser's address bar.
  2. Find MIDI devices and set it to Allow.
  3. Reload this page.

No MIDI device detected. Plug in your MIDI keyboard and click Retry.

MIDI access granted. Select a device below and click Connect to start testing.

Keyboard

Last note Velocity Lag

Event log

Event Note Velocity Channel Lag Flag

What are dead keys on a MIDI keyboard

A dead key is a physical key that fails to send a MIDI Note On message when pressed. On a new keyboard this is almost always a hardware fault: a damaged contact strip, debris under the key, or a broken spring. On older keyboards it can develop over time as the conductive rubber contacts oxidise or wear flat.

The virtual piano on this page lights up every key as MIDI messages arrive. Press each key in turn across the full range. Any key that stays dark when pressed is dead. Because the display maps MIDI note numbers, you can identify the exact note number and report it to a repair technician or manufacturer.

TIP Some keyboards send velocity-zero Note On messages for very light touches. This tool treats those messages as Note Off events so a lightly pressed key does not stay lit. If a key only lights up when pressed firmly, the contact strip is worn, not truly dead, but in need of cleaning or replacement.

Ghost notes — what they are and how to spot them

A ghost note is the MIDI equivalent of a keyboard's double-tap: a single key press produces two Note On messages for the same pitch in rapid succession. In a DAW this shows up as a stacked double-trigger on a single beat, or a sequencer that records two events where you only intended one. The tester flags any duplicate Note On arriving within 30 ms of the previous one so you can decide whether the behaviour is a hardware fault or just an aggressive playing technique.

What a ghost note is

A ghost note is an unintended duplicate Note On event triggered by a single key press. It appears as a second message for the same note arriving within milliseconds of the first. The symptom in a DAW is an unexpected double-trigger: a note plays twice, or a sequencer records two events stacked on the same beat.

This tester flags any Note On message that arrives within 30 ms of a previous Note On for the same pitch with a red ⚠ GHOST marker in the event log. The 30 ms threshold is a tool setting intended to catch rapid duplicate triggers while avoiding most intentional trills and repeated notes in normal playing.

Why contacts bounce and how to fix it

A bouncing contact strip produces multiple electrical pulses per physical press, which the keyboard reports as repeated Note On messages for the same pitch. Firmware on some keyboards includes a double-trigger prevention setting that filters these rapid duplicates before they reach the MIDI output. For keyboards without that firmware option, a MIDI filter plugin in your DAW can suppress events arriving within a configurable time window. Persistent ghosting on a new keyboard that lacks a firmware fix qualifies as a warranty defect worth reporting to the manufacturer.

USB-to-browser input latency

The lag figure shown in the stats bar and event log is the time between the browser receiving the MIDI message and the moment the key was physically pressed. The figure updates with every Note Off event so you can watch the reading change as you play. More precisely, it is performance.now() − event.timeStamp, where event.timeStamp is the timestamp the browser attaches when the USB MIDI packet arrives at the Web MIDI layer.1 This tool shows the difference in milliseconds on every row of the event log. Each new key press refreshes the stats bar while the event log keeps every value so you can compare readings across a run.

This measures processing overhead inside the browser. It captures the time spent queuing and dispatching the event on the JavaScript thread but leaves out the full round-trip to audio output. The number can vary by machine, browser, and current workload. Spikes can indicate main-thread contention such as other tabs, heavy page scripts, or a slow garbage-collection pause.2 For latency-critical work, close background tabs and use a dedicated browser profile.

NOTE USB full-speed links run at 12 Mbit/s, and full-speed interrupt endpoints with a bInterval of 1 use 1 ms polling frames.34 The hardware latency of the keyboard itself is therefore small compared with the software stack this tool measures: OS driver, browser MIDI subsystem, and JavaScript dispatch. Each of those three pieces adds a small delay, and together they produce the number shown in the stats bar.

A worked reading shows how the pieces add up. Suppose the stats bar reports a lag of 4.2 ms for a key press: that figure is performance.now() minus the event.timeStamp the browser attached when the USB packet arrived, so it reflects OS, driver, and JavaScript dispatch overhead rather than the keyboard's own response. A steady reading in the low single digits on an idle machine is normal. If the same key press later reports 25 ms with several other tabs open, the spike points to main-thread contention rather than a hardware fault, and closing background tabs before retesting usually brings the number back down.

Browser compatibility

The Web MIDI API is supported in Chrome 43+, Edge 79+, Opera 30+, and Firefox 108+; Safari does not implement it.5 The same Chromium-based engine also brings support to Chrome for Android and Samsung Internet 4+, and other Android browsers such as the legacy Android browser and UC Browser for Android now support the API as well. Safari has no current support, and you can follow the WebKit tracking bug listed in the compatibility tables to watch for changes. A Web MIDI API polyfill exists for projects that need to target unsupported browsers, though it requires a separate dependency and does not cover every method.

On first use, Chrome will show a permission prompt asking to allow MIDI device access. This prompt is per-origin and persists until you reset it via the lock icon in the address bar.6 If you dismissed the prompt accidentally, click the lock icon, find MIDI devices, set it to Allow, and reload the page.

Hot-plugging is fully supported. Connect or disconnect your keyboard at any time and the tool will detect the change automatically without needing a page reload.7 Browsers make this possible by firing a statechange event on the MIDIAccess object whenever a port appears or disappears, so the page can react the moment a keyboard is plugged in or unplugged. The Web MIDI specification defines this notification as a MIDIConnectionEvent, which means supported browsers handle live device changes through events rather than by polling the port list over and over.

MIDI velocity, note data, and what the event log shows

Every MIDI Note On message carries three values packed into a status byte and two data bytes, and understanding what each one represents is the key to reading the event log with confidence. The channel selects which instrument or track receives the event, the note number maps to pitch, and the velocity encodes how hard the key was pressed. Together they describe everything the DAW needs to reproduce the performance.

The three values in a Note On message

Every MIDI Note On message carries three values: the channel (1 to 16), the note number (0 to 127), and the velocity (0 to 127). The MIDI Association describes Note On as a channel message with a status byte identifying one of sixteen channels, followed by key number and velocity data.8 Channel identifies which instrument or track receives the event. Note number maps to pitch, with middle C being note 60 by the most common convention, though some manufacturers label that pitch C3 while others call it C4.9 Velocity encodes how hard the key was pressed; most synthesisers and DAWs translate it to volume, timbre brightness, or both depending on how the patch is programmed.

Velocity response and curves

Velocity response is where significant quality differences between keyboards surface. A cheap controller may quantise velocity into just a few coarse bands rather than distributing responses smoothly across the 1 to 127 range. Pressing the same key repeatedly at different intensities and watching the velocity values in the event log reveals whether the response is linear, stepped, or inconsistent across the range. Some keyboards ship with configurable velocity curves that adjust the relationship between physical press force and the transmitted value. Checking the raw velocity output here gives you a baseline before any curve is applied, so you can judge whether uneven dynamics come from the hardware itself or from a curve setting that needs adjustment in the keyboard software.

Aftertouch

Aftertouch, if your keyboard supports it, is a second pressure value sent after the initial keystroke. Channel aftertouch sends a single value for all held notes simultaneously. Polyphonic aftertouch sends per-note values independently, which requires more sophisticated hardware and rarely appears on entry-level controllers.8 Both message types appear in the event log alongside Note On and Note Off entries, letting you confirm that aftertouch hardware responds correctly before you assign it to a modulation target in your DAW or synthesiser patch. Seeing aftertouch messages appear consistently at moderate pressure confirms the mechanism is working; seeing them only at maximum force suggests the sensor threshold needs adjustment in the keyboard's own settings menu.

Web MIDI Keyboard Latency Tester Reference

  • Duplicate Note On within 30 ms
  • 1 ms

Press keys above and compare your own event log's Lag column and any ⚠ GHOST markers against these figures.

Sources
  1. 1.

    MDN Contributors, "Performance: now() method," developer.mozilla.org, August 2025. https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

  2. 2.

    Jeremy Wagner, "Optimize input delay," web.dev, May 2023. https://web.dev/articles/optimize-input-delay

  3. 3.

    Microsoft Learn, "USB in Windows - FAQ," learn.microsoft.com, accessed June 2026. https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-faq--introductory-level

  4. 4.

    Microsoft Learn, "_USB_ENDPOINT_DESCRIPTOR (usbspec.h)," learn.microsoft.com, April 2021. https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/usbspec/ns-usbspec-_usb_endpoint_descriptor

  5. 5.

    Can I use, "Web MIDI API," caniuse.com, accessed June 2026. https://caniuse.com/midi

  6. 6.

    MDN Contributors, "Navigator: requestMIDIAccess() method," developer.mozilla.org, November 2025. https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMIDIAccess

  7. 7.

    W3C, "Web MIDI API," w3.org, January 2025. https://www.w3.org/TR/webmidi/Overview.html

  8. 8.

    The MIDI Association, "About MIDI-Part 3:MIDI Messages," midi.org, accessed June 2026. https://midi.org/about-midi-part-3midi-messages

  9. 9.

    "MIDI tuning standard," Wikipedia, accessed June 2026. https://en.wikipedia.org/wiki/MIDI_tuning_standard

FAQ