Bot detection: the five signals and their real limits
Bot detection accumulates evidence; it never proves that a client is automated. Every signal it uses can be reproduced by something determined enough. Useful systems therefore combine several weak signals rather than trusting a strong one. If you are working out how to detect bots on your own site, the practical skill is knowing what each signal misses and what it costs when it points at a customer.
The five layers
| Signal | Inspects | Catches | Misses |
|---|---|---|---|
| Declared identity | What the client says it is | Automation that does not bother to lie | Anything that copies a browser string |
| Source reputation | History of the address | Known-bad infrastructure | New sources, residential proxies |
| Behaviour | Actions across many requests | Systematic access, inhuman timing | Slow, low-volume, patient automation |
| Client characteristics | How the client is built | Mismatches between claim and capability | Full browser automation |
| Challenges | Response to a task | Anything unwilling to spend the cost | Automation willing to pay it |
They are listed in order of how easily each is defeated, which is roughly the inverse of how much they cost you when wrong. Whichever bot detection software or tools you evaluate, ask which of these five signals each one actually uses.
Declared identity
The client states what it is. That statement is free to write, so it proves nothing on its own and remains useful for exactly two purposes: it removes automation that never intended to hide, and it flags contradictions.
The contradiction is where the value lies. A client claiming to be a current browser while behaving like a script is more interesting than either fact alone, and inconsistency between a declaration and observed capability is a genuine signal where the declaration itself is not.
- The limit: anything that has been told to hide is invisible here. Blocking on this signal alone catches the automation that was not a problem.
Source reputation
Addresses carry history: what has been seen from them, whether they belong to hosting infrastructure or to consumer networks, and whether they have been observed in abuse elsewhere. That history is real information and it is not about the current request. You can look up how a single address is listed with the address checks gathered there.
- The limit: it is about the address, not the sender. Many people share one address on mobile networks and behind corporate egress, so a reputation decision lands on everyone behind it. And automation running on residential connections inherits the reputation of ordinary homes, which is precisely why that market exists. How scoring is built and where its data comes from is covered separately.
Behaviour
The strongest signal available, because it describes what a client actually did rather than what it claimed.
Access that walks systematically through identifiers, sessions with no pauses, request sequences that skip the steps a person would take, and populations whose members all behave identically: none of these is provable automation, and all of them are unlike how people use a site.
- The limit: it needs volume and time. A client making a handful of requests provides too little to judge, which is the shape that patient automation takes. Behaviour also describes populations better than individuals, so it supports rate decisions more readily than verdicts about one visitor.
Client characteristics
What the client is, as opposed to what it says: which capabilities it actually has, how it negotiates the connection, and whether those details line up with the browser it claims to be.
- The limit, and it has three parts. Full browser automation produces genuine browser characteristics, because it is a genuine browser. Privacy protections in browsers and on devices deliberately reduce how distinguishable clients are, which erodes this signal over time by design. And the technique is close enough to tracking that it deserves a deliberate decision rather than a default: the same measurements that identify automation identify people, and where that data goes is a question worth answering before deploying it.
Challenges
Rather than judging, ask the client to spend something: a computation, an interaction, a proof that costs little once and more at scale.
This is the only method that changes the economics rather than the classification. It also degrades gracefully: a customer who passes is inconvenienced and still served, which makes it the safe choice when confidence is low.
- The limit: automation that finds the target valuable enough will pay the cost, and challenges have their own costs on the other side, falling hardest on assistive technology, older devices, and anyone with a slow connection. A challenge on every request is a tax on your customers.
Combining signals
No single layer decides. Practical systems assign weight to several and act on the total, which has two consequences. Detecting bots in practice means reading that total, not any one layer.
How a network of infected devices behaves is described under what does a botnet do, and automation that collects content under web scraping software.
- Thresholds are policy, not truth. Where the line sits determines how many customers are inconvenienced and how much automation gets through, and there is no setting that avoids both. That choice belongs to whoever bears the cost of each error, which is a business decision rather than a technical one.
- Response should scale with confidence. Low confidence deserves a challenge, medium a limit, and only high confidence deserves refusal. A bot detected at low confidence should never meet the same response as one detected at high confidence. A system with one response for every score is either too permissive or too aggressive at most levels.
How to check if a request is a bot, without a tool
Is this request a bot? A bot test needs no separate service, because your access logs already hold the evidence. Read one request through the five signals above, in this order.
- Compare the claim with the behaviour. Does the client act like the browser it declared: fetch the page's styles and scripts, or only the one address?
- Read the sequence. Pull every request from the same address and session. Even gaps, no pauses, or identifiers visited in order point to a script. One request alone proves nothing.
- Look at the address. Hosting infrastructure or a home network? That is a hint, not a verdict, because many people share one address.
- Set a trap. A form field hidden from people but present in the markup is a honeypot. Honeypot bot detection rests on one idea: people never fill it, so a filled value suggests a script. Treat it as evidence, not proof.
- Weigh the total. Two weak signals that agree are worth more than one that stands alone. A single weak hit deserves a challenge rather than a refusal.
Playwright bot detection by hand is harder: a real browser driven by a framework such as Playwright shows genuine browser characteristics, so step 2 is the one with the most left to read.
Before acting on a rule derived this way, run it in monitor mode, which records what would have been blocked without refusing anyone.
How to know it is working
The question most implementations never answer, because the evidence is uncomfortable to gather.
Automation blocked is easy to count and tells you little. A bot detector that reports only that count leaves out the half that matters. What matters is what you refused wrongly, and that number does not appear anywhere by default: a customer who was blocked leaves, and nothing records the transaction that did not happen.
Two habits produce the missing evidence. Log decisions with the signals behind them, so a complaint can be traced to a rule rather than argued about. And sample what you blocked, deliberately, on a schedule, looking for the ones that should not have been.
The signals that age badly
Two practical warnings about anything you build on these layers.
- Lists go stale in both directions. Addresses change hands, hosting ranges get reassigned, and a source that deserved blocking last year may now serve a customer. A list without an expiry becomes a set of decisions nobody remembers making, which is the same failure described for emergency filters everywhere in this material.
- Rules written against one campaign describe that campaign. Automation adapts, and a rule matching what it did last month keeps matching the handful of clients that still behave that way, most of which are no longer the ones you care about. Rules built on structural properties, such as cost consumed or systematic access, survive changes that rules built on specific strings do not.
The practical rule is that anything specific should expire on its own, and anything permanent should be structural.
Detection as part of the stack
Bridge WAF classifies automation by declared identity, which is the first and weakest of the five signals above. That is worth stating plainly rather than implying more: reputation scoring, client characteristics, and behavioural analysis are not what it does.
What it does provide is the part this page argues matters most. Monitor mode records what would have been blocked without acting on it, which is the observation step that makes false positives visible before they cost anything. Rate limiting applies per domain. Flagged requests appear in a near-real-time activity log, so a decision can be traced rather than argued about. Modes are off, monitor, and block, with nothing to tune between them. See what the platform offers at Bridge CDN.
Questions
Can bot detection be certain?
No. Every signal available can be reproduced by something determined to reproduce it, so detection accumulates evidence towards a probability rather than establishing a fact. Building a system that acts as though it has proof is what produces confident, damaging mistakes.
Which signal is most reliable?
Behaviour observed across many requests, because it describes what a client actually did rather than what it declared about itself. Its weakness is the mirror of its strength: it needs a run of requests before it says anything, so it is useless on a first visit.
Why is blocking by declared identity weak?
Because the declaration is written by the client and can say anything at all. Acting on it removes exactly the automation that was being honest about itself, while everything concealing its nature continues untouched, which inverts the outcome you were aiming for.
Is fingerprinting a good idea?
Partly. Fingerprinting carries real signal and real costs together. Browsers are deliberately reducing what it can see, automation driving a genuine browser defeats it outright, and whatever it measures it measures about your customers as much as about anyone else, which raises questions beyond the technical.
When should challenges be used?
Wherever confidence is low, which is most of the time. The response should scale with certainty: high confidence justifies refusal, moderate confidence justifies a challenge, and low confidence justifies watching, because each mistake costs in proportion to the force used.
How do I measure false positives?
Deliberately, because nothing surfaces them on its own. Record the signals behind every decision, and sample blocked traffic on a schedule to see who was in it. A blocked customer files no report, so a system with no sampling reports perfect accuracy indefinitely.
How do I detect a bot on my site?
Look for several weak signals at once rather than one strong one. Declared identity catches automation that does not hide, source reputation flags known-bad addresses, behaviour shows systematic access across many requests, client characteristics expose mismatches between claim and capability, and challenges make the client spend effort. None of them proves anything alone, so act on the combined picture and let the response scale with confidence. Bridge WAF itself works from declared identity only, which is the first and weakest of the five.