Detection · Sep 25, 2026 · 4 min read
Behavioral biometrics: 11 mouse measures against 120 people
How behavioral biometrics tell an automated mouse and keyboard from a person, the 11 pointer measures we track against 120 people, and the 5 still outside.

In short
A browser can pass every fingerprint check and still move like a machine. The pointer jumps to a button in a straight line, keys arrive at a constant rhythm, and a site that records input events can see it. We measure our input layer against 120 recorded people on 11 pointer measures. Six are inside the human band today and five are not, and this article shows all eleven.
What are behavioral biometrics?
Behavioral biometrics are the measurements a site takes from input events rather than from the device: pointer speed and path, the rhythm of key presses, pauses, scrolling and the order in which events arrive. The research behind it is published. In BeCAPTCHA-Mouse, Acien, Morales, Fierrez and Vera-Rodriguez trained a classifier on real and synthetic mouse trajectories in 2020 and report that it "is able to detect bot trajectories of high realism with 93% of accuracy".
A measurement only means something against real people, and one person is not enough. Our pointer targets come from the SapiMouse dataset, which "contains mouse dynamics data from 120 subjects" recorded with a JavaScript web application on their own computers, so the events went through a browser exactly as ours do.
Which 11 measures separate a bot from a person?
Eleven pointer measures separate a synthetic pointer from people in our bench, from the spacing between events to the path length against the straight line. For each one we compare our value with the band between the 10th and the 90th percentile of the 120 people.
| Measure | Scalebrowser | 120 people, p10 to p90 |
|---|---|---|
| Gap entropy, bits | 2.87 | 1.97 to 2.94 |
| Speed, pixels per ms | 0.696 | 0.343 to 0.846 |
| Acceleration | 0.140 | 0.130 to 0.293 |
| Jerk | 0.214 | 0.185 to 0.412 |
| Path length against the straight line | 1.12 | 1.06 to 1.66 |
| Frames with more than 1 sample | 0.265 | 0.12 to 0.55 |
| Gap median, ms | 27.5 | 13.9 to 17.0 |
| Gap variation, CV | 0.476 | 0.923 to 1.24 |
| Most common gap, share | 0.262 | 0.384 to 0.583 |
| Angle change, radians | 0.062 | 0.080 to 0.136 |
| Direction reversals per 100 samples | 2.77 | 0.564 to 2.25 |
The first six rows are inside the band, the last five are not. A second group of signals is categorical, and those are closed: a pressed button reports a pressure of 0.5, coalesced sub-events appear in 26 percent of frames against a reference of 25 percent, every pointer, mouse and click chain is complete, 99 percent of typed text arrives as insertText, and every focus change is explained by a click or a Tab.
Why does added jitter make it worse?
Added jitter makes a synthetic pointer worse because it produces movement no real trace contains, and bot detection compares pointer paths with people. An earlier version of our input layer shook every path with a tremor model, and the paths reversed direction 4.5 times per 100 samples where a person on the same bench reversed 0.27 times, 17 times as often.
Human tremor moves far less than one pixel, so it never reaches a page as an event, and injecting it adds a pattern instead of hiding one. The whole story, together with the same mistake on canvas, is in our write-up on noise in pointer paths.
What about typing?
Typing is calibrated the same way, against a cohort instead of one person. Our keyboard targets come from the 136 million keystrokes that 168,000 volunteers typed in an online study by Dhakal, Feit, Kristensson and Oulasvirta, published at CHI 2018. Each profile gets its own typing speed and key hold times drawn from that population, so two profiles do not type with the same rhythm, and the layer targets the study's rates for corrections and overlapping key presses.
What is still open?
Five pointer measures are still outside the band, and three of them share one root. Our pointer events arrive a median 27.5 milliseconds apart, where people sit between 13.9 and 17.0, so the stream is too sparse, and a sparse stream also has too little variation between gaps and too few gaps of the most common length. Angle change is too low on its own, and direction reversals, down from 4.5 to 2.77 after the tremor came out, are still above the band.
We publish these rows because they are the next work, not because they are finished. A measure that sits outside the human band on every run is a pattern a classifier can learn, whatever the other ten measures say.
What should you measure in your own agent?
Record your agent's input events on a page you control and compare them with a cohort of people, measure by measure, on the same event path a site sees. Use percentile bands, not averages, and never tune against a single recorded person: in our first calibration a single recorded person disagreed with the cohort on four of ten pointer measures. The human input page of the documentation describes how Scalebrowser produces pointer paths and typing rhythm and what an agent can control about them.
Run it on your own machine
Seven days to try it with your own agents on your own sites. Starting the trial needs a card.