Detection happens on three independent planes. Each one alone is defeatable, and essentially every existing tool uses exactly one of them. The power is entirely in correlating them.
Figure 1 — three independent observations, one cross-checked verdict per session. A verdict with no reasons attached is treated as a bug in the software, not as a terse answer.
| Plane | Source | What it sees |
|---|---|---|
| 1. Transport | the access log line | Headers, ASN, reverse DNS, protocol, status, timing |
| 2. Behaviour | correlation across lines | Asset ratio, cache behaviour, session shape, inter-request timing, and cross-IP fingerprint clusters |
| 3. Execution | the JavaScript beacon | Whether JavaScript runs at all, whether the engine matches what the User-Agent claims, whether a human is driving |
Log-only analysers see plane 1 and nothing else. JavaScript-only analytics sees plane 3 — and trusts it: a client that runs the script is a human, as far as it is concerned. Nothing in common use correlates the two, which is why headless Chrome on residential proxies is counted as human traffic almost everywhere.
The interesting part is that the two planes are defeated by opposite things. Looking more like a browser — running a real engine, fetching every sub-resource, executing the analytics script — makes plane 3 easier to pass and plane 2 harder, because it leaves a richer, more consistent behavioural trace to compare across addresses. Defeating plane 3 without also defeating plane 2 is precisely what gives a fleet away.
The core idea of the product, in four rows.
| Plane 1 (the log) | Plane 3 (the beacon) | Verdict |
|---|---|---|
| HTML 200 served | no beacon ever arrived | bot — a non-JS client |
| HTML 200 served | beacon arrived, headless signals positive | bot — headless automation |
| HTML 200 served | beacon arrived, zero interaction, one page, gone in under ten seconds | unknown — 55 points, and deliberately short of a verdict |
| HTML 200 served | beacon, interaction, plausible timing distribution | human |
A session with no interaction that left quickly scores 55 — forty points for no interaction plus fifteen for a single short page — which lands in unknown, not likely_bot. unknown is a real answer here and it is used: that session is one Loghound does not have enough evidence about, and saying so is more useful than guessing. The threshold to reach likely_bot is 60, and these two signals together do not get there.
- Plane 1 and 2 work with no cooperation from your site. Point Loghound at an access log and it already does asset ratios, session shape, request-rate periodicity and fingerprint clustering.
- Plane 3 needs one script tag. Without the beacon, headless automation is inferred rather than proven, and time on site falls back to the weak log-derived number every other log analyser reports.
- A beacon-only session is marked as such and never claims a log-backed fact. Five rules that read the transport plane are silenced on it, because an absent counter must never be read back as a zero and then used as evidence. See standalone mode.
Next: the fingerprint cluster, which is the single strongest signal on plane 2, and the scoring rules, which are how the three planes become one number.