keyboard
Keyboard Ghosting and N-Key Rollover, Explained
Why cheap keyboards drop keys when you hold three at once, what NKRO actually requires over USB, and why a browser-based keyboard test can never see quite everything.
Hold Ctrl, W, and A on a budget keyboard and one of them stops registering. Hold a fourth and a key you never pressed shows up instead. Both symptoms come from the same place: a keyboard doesn’t have a wire per key, and the shortcut it takes instead is ambiguous by construction.
The matrix, and why it exists
A full-size keyboard has about 104 keys. Wiring each one back to the controller would need 105 conductors and a microcontroller with 105 pins. Nobody does that. Instead, keys sit at the intersections of a grid — say 8 rows by 18 columns, which covers 144 positions using 26 pins.
The controller scans the grid continuously: energize row 1, read all columns, note which are connected; energize row 2, and so on, hundreds of times per second. A key press closes the switch at its intersection, so “row 3, column 7 is connected” means “the D key is down.”
This works perfectly for one key. It works for two. It breaks at three.
Ghosting: the phantom fourth key
Picture three keys pressed that happen to form an L on the matrix — two sharing a row, two sharing a column:
col 2 col 5
row 1 [ A ] [ B ] A, B, C pressed
row 4 [ C ] [ ? ] ? = not pressed
A connects row 1 to col 2. B connects row 1 to col 5. C connects row 4 to col 2. Now trace the current: from row 4, through C, onto col 2, back up through A onto row 1, across through B, and out onto col 5. The controller energizes row 4, reads column 5 as connected, and concludes that the key at row 4 / column 5 is pressed.
It isn’t. Nobody touched it. That’s a ghost key — the fourth corner of the rectangle, hallucinated by a circuit that has no way to tell a real connection from a path through three other switches.
The electrical fix is a diode at every intersection, so current can only flow one direction and the return path through A is blocked. That’s it — that’s the entire difference. It costs cents per keyboard and is the single clearest dividing line between a keyboard that handles simultaneous keys and one that doesn’t. (The “N” in NKRO keyboards’ marketing copy is really just “we paid for the diodes.”)
Blocking: the fix that’s also a problem
Manufacturers know about ghosting, and a phantom keypress is much worse than a missing one — imagine a game firing a weapon you didn’t ask for, or a random letter appearing mid-sentence. So most diode-less keyboards deliberately do the safer thing: when the controller detects an ambiguous pattern, it refuses to report the third key at all.
That’s blocking (or jamming), and it’s why modern cheap keyboards rarely produce phantom characters but constantly drop inputs. If you’ve ever held a movement key plus a modifier and found that a third key does nothing, you’ve hit blocking, not a broken switch.
Manufacturers then hand-tune which key combinations are protected. This is why WASD plus common modifiers almost always works even on a $15 keyboard — the matrix layout is arranged so those particular keys don’t collide — while some arbitrary trio elsewhere on the board fails immediately. Rollover isn’t a single number; it depends on which keys.
The USB side: why 6 is a magic number
Even with a perfect diode-per-key matrix, there’s a second bottleneck: how the keyboard reports what it sees.
The USB HID specification defines a boot protocol for keyboards — a minimal, fixed report format that a BIOS or bootloader can understand without parsing a full HID report descriptor. That report is 8 bytes: one modifier bitmask, one reserved byte, and six slots for keycodes.
Six. That’s where “6KRO” comes from. It isn’t a cost-saving measure or a limitation of USB’s speed; it’s the shape of one specific legacy report format, and modifiers (Ctrl, Shift, Alt, Meta) live in the separate bitmask so they don’t consume slots. Six non-modifier keys plus any modifiers is the boot-protocol ceiling.
True NKRO over USB requires the keyboard to describe a different report format in its HID descriptor — typically a bitmap report, one bit per possible keycode, so any number of keys can be simultaneously “on.” Some keyboards achieve it by presenting multiple HID endpoints and spreading keys across them. Either way it works fine in modern operating systems, but it’s outside the boot protocol, which is why NKRO keyboards often have a switch or firmware toggle to fall back to 6KRO: some BIOS setup screens and older KVM switches only speak boot protocol.
Worth noting for historical context: PS/2 was natively n-key rollover. It’s an interrupt-driven serial protocol that sends scancodes as they happen rather than reporting a fixed-size snapshot of state, so it never had a six-key ceiling. The move to USB was a regression on this specific axis, later patched around.
| Mechanism | Simultaneous keys | |
|---|---|---|
| No diodes, ghosting | Matrix ambiguity unhandled | 2 reliable; phantom keys beyond |
| No diodes, blocking | Ambiguity detected, extra keys suppressed | 2 reliable, plus hand-tuned combos |
| Diodes + USB boot protocol | 6 keycode slots + modifier bitmask | 6 + modifiers |
| Diodes + USB NKRO report | Bitmap report descriptor | All of them |
| PS/2 | Serial scancodes on change | All of them |
What a browser test can and can’t see
A web-based keyboard test reads keydown and keyup events. That’s enough to do genuinely useful things — light up a visual board, log every event, and count how many keys are held simultaneously to measure your actual rollover — but the browser sits at the end of a long chain, and a few things are consumed before it.
key vs. code. These are different and the distinction matters when diagnosing:
event.codeis the physical key position, layout-independent. Press the key where QWERTY puts Q and you getKeyQ— even on AZERTY, where it types an A.event.keyis what the key produced, after layout, modifiers, and dead keys. Same physical key:q, orAon AZERTY, orQwith Shift.
If a key is “not working,” code tells you whether the switch registered at all; key tells you whether your layout is mapping it somewhere unexpected. A key that produces the wrong character is a layout problem, not hardware.
Keys the browser never receives. The OS and the browser both intercept before the page:
- OS-level combinations (Cmd+Tab, Alt+Tab, Win, the screenshot shortcuts) are usually swallowed entirely.
- Media keys, brightness, and most function-row secondary actions never reach the DOM.
- Browser shortcuts (Ctrl/Cmd+W, Ctrl/Cmd+T, F11, F12) may be handled by the browser first. A page can call
preventDefault()on some of these, but doing so risks trapping the user — which is why our keyboard test only suppresses defaults while the test area is explicitly focused, and never suppresses Escape or anything held with Ctrl/Cmd. You can always get out.
Quirks that inflate rollover counts. Two real ones worth knowing if your measured maximum looks implausible:
- macOS with Command held: while Cmd is down,
keyupevents for other keys are frequently not delivered. Press a few keys with Cmd held and the page believes they’re still down, because it never heard them released. - Caps Lock is a toggle, not a momentary key, and reports inconsistently across platforms — you may get a
keydownwith no matchingkeyupuntil the next toggle.
Both leave stuck keys in the “currently held” set. If a rollover test reports a suspiciously high number, release everything, click away and back, and try again without Cmd involved.
Testing your own keyboard
To find your real rollover limit: press and hold keys one at a time, adding a new one without releasing any, and watch the held-key counter. Do it in a few different regions of the board — remember that rollover is combination-dependent, so a good result on WASD tells you nothing about the number row.
To find a dead key: press it and watch whether any event appears. Nothing at all points to the switch or the matrix. An event with an unexpected key value points to your keyboard layout. A key that works alone but vanishes in combination is rollover, not failure.
- Keyboard Test — visual board, live event log with
keyandcode, and a rollover counter. Keystrokes never leave your device. - Screen Test, Mic Test, Webcam Test — the rest of the hardware checks.
- ASCII Table — for when you need the code behind the character.