AI SEO In Detail

AI SEO In Detail › Module B · Search Traffic Analysis › Episode 15

Episode 15 · coming soon

Is Your Traffic Real? Filtering Bots in GA4

Episode 15 of AI SEO In Detail, a free course in practical SEO analysis: Is Your Traffic Real? Filtering Bots in GA4.

Episode 15: Is Your Traffic Real? Filtering Bots in GA4 Video coming soon

This episode is scripted and in production. The transcript below is the script as written; it may change before the video is published.

Full transcript

1,288 words · script draft, under review.

Intro

A while ago, one of my dashboards showed a site doing really well. Over fifty thousand sessions. I was pleased, for about a minute.

Then I filtered by hostname. That's the domain the visit was recorded on. About fifty-five sessions came from the site's actual domain. The rest, over fifty thousand, came from somewhere else entirely.

Nothing was broken in the usual sense. The numbers were just not what I thought they were. In this episode I'll show you how that happens, the one filter that would have caught it, and how to spot bot traffic that gets past it.

What happened

A note on this data. It's real, from one of my own sites, but anonymized: no domain names, no URLs, nothing that identifies the site. The numbers are what Analytics reported.

Here's what happened. The site had moved to a new domain. The old domain was retired, but the Google Analytics property, the container that collects the data, was reused for the new one. That's common. It saves setting things up again.

But a property doesn't know which domain it belongs to. It accepts data from anywhere that sends it its ID. And the retired domain kept getting hit by bots, which were counted as sessions in the same property.

So the dashboard added it all together. Over about five weeks: fifty-three thousand five hundred and seventy-four sessions on the retired domain, fifty-five on the current one. Ninety-nine point nine percent of what it showed was noise.

Filter one: hostname

The fix is one dimension: hostname. Every event in Google Analytics records the domain it came from. Break your sessions down by hostname, and you'll see every domain that sent data to your property.

That incident was on a different site. So let's run the same check on the site we'll use for the rest of this episode, example-city-stats.com, one of my own, anonymized the same way. On screen is every hostname that sent it data over the last ninety days.

And it's clean. Two rows. The site's own domain, with about fifty-five thousand sessions, and the www version, with six. No old domains, no strangers. This is what a healthy property looks like. The point is to see this list, not to assume it.

On a property with problems, you'd see more rows: an old domain, a test server, a translation proxy, or a domain nobody recognizes. All of them are noise in a report about your site.

Keep only the hostnames that are yours, and live. Do it in every report and every API query, before any other analysis. I put that filter inside the one shared function all my scripts use to query Analytics, so I can't forget it.

And check it every time a domain changes. Before you reuse a property, ask it one question: sessions by hostname.

Bots that get past the filter

Google Analytics already excludes known bots automatically. You can't switch that off, and you can't see what it removed. What reaches your reports is the traffic that didn't look like a known bot.

Some of it still isn't human. Here are the patterns I look for.

Zero engagement. Sessions with no engagement time at all, one page, then gone. Real visitors bounce too, but not by the thousands in a neat block.

One place. A sudden group of sessions from a single city or a single country that has nothing to do with your audience. Often that's where a data center is.

Odd timing. Spikes of direct traffic at three in the morning, every night, with no campaign behind it.

Missing values. Language, screen size or landing page showing as "not set". A real browser fills those in. A script that sends data straight to your measurement ID often doesn't.

None of these is proof on its own. Look for two or three at once, in the same segment. That's when you can be fairly sure.

Engagement as a signal

A useful summary number is engagement rate. Analytics counts a session as engaged if it lasts more than ten seconds, includes a key event, or views at least two pages.

Next to it, look at average engagement time per session. Real visitors produce a spread. Bots tend to produce the same few seconds, again and again.

For my site as a whole, about fifty-five percent of sessions are engaged, at around forty-five seconds each. Now break it down. By country, the United States, where the audience is, sits at about sixty-one percent engaged and fifty seconds. Then come Singapore, Brazil and Hong Kong, with between seven hundred and twelve hundred sessions each, and two to three seconds of engagement. Brazil and Hong Kong are under ten percent engaged.

By landing page, one row is called "not set": almost twelve hundred sessions, two percent engaged, under three seconds. A real visit lands on a page. That's the missing-values pattern sitting right on top of the zero-engagement pattern.

And direct traffic: about fifteen thousand sessions, under thirty percent engaged, fourteen seconds. Lower than search, which is normal, but big enough to watch.

None of this proves bots on its own. But a few thousand two-second sessions from countries outside the audience is exactly the kind of cluster I don't count as growth.

The Search Console sanity check

Here's the cross-check I trust most. Search Console counts clicks from Google search on Google's side. Analytics counts sessions from Google organic on your side. They'll never match exactly.

Often Analytics is lower. Some visitors decline cookies or block tracking. That's normal.

On my site it's the other way round. In every one of these sixteen weeks, the organic channel in Analytics shows more sessions than Search Console has clicks, about one point six times as many. But that channel counts every search engine, not just Google. Bing, DuckDuckGo and Yahoo together sent almost ten thousand organic sessions in the last ninety days.

So narrow Analytics to Google as the source, and compare again. Now the lines almost meet. From late June to the end of August, Google sessions stayed within about twelve percent of Google clicks, week after week. That's a difference in counting, nothing more.

Then the ratio starts to climb. Seventeen percent more in early September, then around twenty, then thirty-four, and in the last week, half again as many sessions as clicks. Google can't have sent visitors it didn't count. So since late August, something extra is being recorded as Google organic.

I don't know yet what it is. It could be bots sending a fake Google referrer. It could be a change in how one of the two tools attributes visits. That's the point of this check: it doesn't give you the answer, it tells you where to dig. A steady ratio is fine. A drifting ratio is a question.

This is the habit from episode one: never trust one source alone.

What to do with bad traffic

Once you've found bot traffic, three steps.

First, segment it out of your analysis. Data that's already in Analytics can't be deleted, so the filter has to live in your reports and your queries. That's another reason to have one shared query function.

Second, write it down. Keep a short list of known-bad hostnames, sources and patterns, with the date you found them. Your future self will need it when an old chart suddenly looks strange.

Third, stop the source where you can. If a retired domain still carries your tracking tag, remove it, or shut the domain down properly. Fewer bad hits coming in means less filtering later.

Wrap-up

So: filter by hostname first, look for bot patterns in clusters, check Analytics against Search Console, and keep the bad traffic out of every number you report. The bot-filter checklist is linked in the description. Next episode: when traffic drops, a step-by-step checklist to find out why.