How to Tell If Your GA4 Traffic Spike Is Bots
GA4's own bot filtering only strips known IAB and Google-listed crawlers — it does not catch headless-browser scraping or Measurement Protocol hits sent straight at your property ID, and both of those read as normal sessions. Before you celebrate a traffic spike, check three numbers: average engagement time, returning-user rate, and Direct's share of sessions. If engagement is under 15 seconds, returning users are under 5%, and Direct is over 80%, you're looking at automated traffic, not growth.
Every Wednesday. 28,400+ operators. Zero fluff.
✓ Check your inbox — click the confirmation link to complete sign-up.
✓ You're subscribed!
✓ You're already on the list.
Published August 2026.
TL;DR: GA4’s own bot filtering only strips known IAB and Google-listed crawlers — it does not catch headless-browser scraping or Measurement Protocol hits sent straight at your property ID, and both of those read as normal sessions. Before you celebrate a traffic spike, check three numbers: average engagement time, returning-user rate, and Direct’s share of sessions. If engagement is under 15 seconds, returning users are under 5%, and Direct is over 80%, you’re looking at automated traffic, not growth.
Operator’s read: I pulled this site’s own GA4 numbers while writing this post. Direct was 77.8% of sessions, average engagement time was 12 seconds per active user, and only 0.5% of users came back. Every one of those numbers individually has an innocent explanation. Together, they don’t. That combination is why I no longer trust a session count until I’ve run it through the checklist below — and why I’d tell you not to either.
A traffic spike is exciting precisely because it’s supposed to mean something: content that’s working, a channel that’s paying off, momentum you can point to. That’s exactly why it’s worth 10 minutes to confirm the spike is people and not scrapers before you act on it — reallocate budget, tell a client it’s working, or use the window as a baseline for anything you’ll measure against later.
Table of contents
Open Table of contents
Why GA4’s bot filtering doesn’t save you
GA4 has always-on bot filtering, and there’s no toggle for it — Google removes traffic matching the IAB/ABC International Spiders and Bots List automatically, before it ever reaches your reports. That’s real, and it’s why the counts you see aren’t raw. But the list is a known-bots list. It catches identified crawlers that announce themselves. It does not catch:
- Headless-browser scraping. A script running Puppeteer or Playwright with a real Chrome user agent looks, to GA4, exactly like a person with a browser open. Nothing in the request identifies it as automated.
- Measurement Protocol hits sent directly at your property ID. GA4’s Measurement Protocol is a public API. If your property ID leaks — and
gtag.jsships it in plain text to every visitor’s browser — anyone can script events straight at your property with no page load involved. This shows up as sessions with no corresponding real traffic anywhere else: no server log hit, no ad spend, no referral source that explains it.
Both look like normal, filtered, legitimate sessions in your reports. The IAB list protects you from the bots that identify themselves. It does nothing for the ones that don’t.
The three numbers that catch what the filter misses
Run any spike through these three checks before you act on it. None of them alone proves anything — a single short session, one non-returning visitor, one Direct hit are all completely normal. It’s the combination that’s the tell.
1. Average engagement time per active user
Threshold: under 15 seconds is suspicious.
A real visitor reading even a short page spends more than 15 seconds on it — scrolling, reading a headline, deciding whether to stay. A script that hits a URL, records the pageview event, and moves to the next URL in its list doesn’t. If your average engagement time across a spike is in single digits, most of that “traffic” never actually looked at anything.
2. Returning-user rate
Threshold: under 5% is suspicious for a spike that’s supposed to represent real audience growth.
A real audience — even one you’re just starting to build — comes back. Someone who found you through a search, liked what they read, and has a reason to check back shows up as a returning user within a few weeks. A one-shot scraping run or a burst of Measurement Protocol junk never returns, because there’s no person behind it with a reason to.
This is the number I trust most, because it’s the hardest one to fake by accident. Legitimate traffic sources — even paid ads to strangers — still produce some returning users over a few weeks. Pure bot traffic essentially never does.
3. Direct’s share of total sessions
Threshold: over 80% is a flag, not a verdict.
This is the one to use carefully. Some Direct traffic is real but untagged — people opening a saved link, a native app webview stripping the referrer, an AI assistant’s citation link landing without a UTM. High Direct alone doesn’t mean bots. But when it’s combined with short engagement and near-zero returning users, it stops being “untagged real traffic” and starts being the default bucket that automated hits fall into when they carry no referrer at all.
Read it as a prompt to investigate, not a measurement of bot traffic on its own. Don’t kill your Direct channel over one number.
Running the check
Pull a GA4 report — the standard Reports snapshot or a Explore workspace — for the window your spike covers, and look at all three at once:
| Signal | Looks fine | Worth investigating |
|---|---|---|
| Avg. engagement time / active user | 15s+ | Under 15s |
| Returning users | 5%+ | Under 5% |
| Direct share of sessions | Under 80% | Over 80% |
One flag on its own: shrug and move on. Two or three together, especially on a spike that started suddenly on a specific date with no matching cause (no new backlink, no campaign launch, no press mention): stop trusting the number until you’ve traced the source.
To trace it, segment the spike by landing page, device category, and geography. Bot traffic tends to concentrate — hundreds of sessions all hitting the same three URLs, or all reporting the same device model, or clustering in a handful of data-center-heavy countries you have no real reason to have an audience in. Real traffic is messier than that; it spreads across your content the way real interest spreads.
What to do once you’ve confirmed it
- Don’t build a report, a budget decision, or a client update on the contaminated window. If you’re tracking a “before” baseline for anything — an SEO campaign, a GEO retainer, ad spend ROI — a polluted period poisons the comparison for as long as that baseline stays in use. There’s no reconstructing a clean number after the fact once the window has closed.
- Add a GA4-side filter once you’ve identified the pattern. If the junk clusters on hostname (someone else’s site pointed at your Measurement ID, or a staging environment leaking real traffic tagging), set a valid-hostname filter in GA4’s Data Streams settings. If it clusters on behavior, a session-scoped custom dimension for engagement time under a threshold gets you most of the way, though GA4 doesn’t let you retroactively strip sessions that already landed.
- Block at the edge if it’s sustained, not a one-off. If you’re on Cloudflare, a bot-management or rate-limiting rule stops the next wave before it hits your analytics at all — cheaper than filtering after the fact, and it also stops the load on your actual server.
- Don’t discard Direct wholesale. Some of it is real people you can’t attribute — including a growing share that’s someone reading your content inside an AI assistant’s answer and typing your name into their browser afterward. That’s a real result you’d be throwing away along with the noise. See how I measure AI-search traffic for how to separate that signal from the rest of Direct instead of writing off the whole channel.
FAQ
Does this mean my traffic spike is fake?
Not necessarily — run the three checks first. Plenty of real spikes (a viral post, a mention on a bigger site, a successful ad) show healthy engagement and a normal Direct share. The checklist exists to catch the ones that aren’t, not to make you distrust every increase.
Why doesn’t GA4 just filter this automatically?
The IAB bot list only covers crawlers that identify themselves through known signatures. A headless browser with a legitimate Chrome user agent, or a raw API call to the Measurement Protocol, presents no signature to filter on — from GA4’s side, it’s indistinguishable from a real pageview. Catching it requires behavioral signals GA4 doesn’t apply automatically, which is exactly why the manual check matters.
How long should I wait before trusting a spike?
Long enough to see whether returning users show up — I’d give it two to three weeks minimum. A spike that still shows near-zero returning users after that window, combined with short engagement, is not becoming real audience with more time. It’s just more of the same traffic.
Every Wednesday. 28,400+ operators. Zero fluff.
✓ Check your inbox — click the confirmation link to complete sign-up.
✓ You're subscribed!
✓ You're already on the list.
Related posts
How to Measure Traffic From AI Search
Updated for 2026. How I measure AI-search traffic from ChatGPT, Perplexity, and Claude — referrer tracking, the dark-traffic problem, and what to trust.
SEOGEO Audit Pricing: What to Charge Clients
How I structure and price a GEO audit — the flat-fee scoping approach, what belongs in the deliverable, and when to convert it into a retainer.
GEOHow to Get Cited by AI Search Through Reddit
AI Overviews and ChatGPT lean on Reddit threads more than most company blogs. Here's how to show up in them without astroturfing, buying upvotes, or bans.
Get the AI playbook in your inbox
Every Wednesday. 28,400+ operators. Zero fluff.
Check your inbox.
We sent you a confirmation email — click the link inside to complete your subscription. Check spam if you don't see it within a minute.
You're subscribed.
Welcome — the next edition lands in your inbox soon.
You're already on the list — look for it every Wednesday.