Skip to content

Build1 publisher3 min readPublished

A global false-positive rate stays 0.2% when every block lands on one carrier

A dev.to walkthrough shows how a bot detector can score 99.7% accuracy while getting nearly one bot verdict in five wrong, and why only per-route counts of challenged known-human sessions show where the blocking lands.

The Engineer · Build desk

Illustration accompanying A global false-positive rate stays 0.2% when every block lands on one carrier

What happened

  • A dev.to post argues that bot-protection accuracy cannot be reported as a single number and has to answer what happens to real people once the policy leaves the dashboard and starts controlling traffic.
  • At one million legitimate requests per day, the post puts that 0.2% at roughly 2,000 customer requests receiving the wrong treatment every day.
  • Its central warning is that a vendor can report a low global false-positive rate while the damage concentrates on one browser, one mobile network or one high-value route.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • cost The two error types are not priced alike in the post's framing: a missed scraper costs bandwidth or content, while a blocked customer costs a sale and a support escalation, so the false-positive column is the one attached to revenue.
  • decision A team running blocks, challenges and monitoring off one score now has to pick three thresholds, because the metric worth optimising changes with the action the score triggers.
  • constraint A vendor's false-positive number is only as good as the sample it was measured on, so a buyer cannot use it without knowing the browser, network and assistive-technology composition of the known-human set behind it.
  • exposure Teams that label non-converting sessions as bots let the detector supply its own ground truth, and the customers it wrongly blocked enter the training data as bots.

Two hundred false positives against 99,000 known-human requests is 0.202% [2][19]. The figure does not move when those 200 change address. Spread them evenly over every route and it holds. Land all of them on one carrier's mobile users at checkout and it still holds [19]. A ratio taken across the whole known-human population has already discarded the partition, so concentration shows up only in a per-route count. The dev.to post asks for that count directly: how many known-human sessions each rule challenged or blocked on each protected route, and what happened next [8].

Accuracy flatters the detector for a second reason. Most requests on a customer-facing app are legitimate and the attacks worth stopping are a small slice [25], so in the post's example a detector that called all 100,000 requests human would score 99% [26]. The one that catches 900 of the 1,000 attacks scores 99.7% [3]. It also issues 1,100 bot verdicts, 200 of them wrong, which is 18.2%, or one in 5.5 [20]. The post describes this as "a bot verdict that is wrong almost one time in six" [5]; one in six is 16.7%, so the worked example is slightly worse than its own description [21].

The metric you gate on depends on which action fires. The post cites Google's classification metrics guide for the coupling: change a threshold and precision, recall and the false-positive rate all change, and no threshold can be evaluated independently of the cost of each kind of mistake [10]. Hence three operating goals rather than one: hard blocks favor precision, challenges balance precision and recall because they leave a recovery path, and monitoring favors recall because a person or a later rule reviews the signal before enforcement [11].

The expensive part is the label set. Strong human labels come from successfully authenticated sessions, completed purchases that were not reversed, support-confirmed sessions, or employees following a controlled test plan, and the post grants that none of these is perfect alone [12]. Two shortcuts are ruled out: calling every session that failed to convert a bot, and calling every session that passed a JavaScript check human, because both put the detector's own assumptions into its ground truth [13]. Genuinely ambiguous traffic stays labeled unknown [13]. Search crawlers, uptime monitors, accessibility scanners, payment callbacks and partner integrations go into the set as automated traffic that is not hostile [14].

A vendor's global false-positive rate describes the population it was measured on [7]. For it to describe yours, that known-human set would need your desktop and mobile browser mix, your older devices and slow connections, and your traffic behind corporate networks, universities and carrier-grade NAT [15]. It would also need the VPNs and privacy tools your customers actually use, plus assistive technology and keyboard-only navigation [15]. The post says: "If the known-human set contains only employees on recent MacBooks, the benchmark is measuring employee laptops, not customers" [16].

A clean lab set with one Chrome version and a few obvious Selenium scripts proves the code runs, and does not establish that the detector is safe for customers [23]. On the automated side the post asks for controlled clients driven by Playwright, Puppeteer, Selenium and curl, plus slow bots, distributed low-volume clients, headless browsers and scripts carrying realistic headers [24]. Every verdict gets its configuration recorded: engine version, rule and threshold version, the signals that fired, score and proposed action, route group, session identifier [17].

What to watch

  • Whether any bot-protection vendor publishes the composition of the known-human set behind its false-positive number.
  • Whether per-route counts of challenged known-human sessions appear in vendor dashboards, or stay something customers have to log themselves.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories