Why no two analytics tools agree on your traffic

Google Analytics says one thing, Search Console another, your server logs a third. None of them is broken. They count different things, and once you know which, the gaps stop being worrying.

9 min read

In this article
  1. 1Start with what each tool can see
  2. 2Bots, crawlers and other things that aren't people
  3. 3Ad blockers and privacy browsers
  4. 4The cookie banner
  5. 5What counts as one visitor
  6. 6Sessions, bounces and other words that don't travel
  7. 7Time zones, and the day that isn't over yet
  8. 8Single-page apps
  9. 9A ten-minute check for your own site
  10. 10Which number to use for what

Put two analytics tools on the same website for a week and they will disagree. Not by a rounding error, either. One reporting half of what the other does is normal, and your server logs or Cloudflare dashboard can easily show more than both of them put together.

We build an analytics tool, so we hear the question a lot, usually as “which one is right?” The honest answer is that most of them are right about what they count. They just don't count the same thing, and the labels hide it. “Visitors”, “users” and “sessions” sound interchangeable. They almost never are.

Here's where the gaps come from, roughly in order of how much they tend to matter, and a quick way to check your own site.

Start with what each tool can see

Every number on an analytics dashboard is a filtered count of things that happened. The filter is the part that differs, and it differs a lot more than the dashboards let on.

SourceWhat it countsCompared with the rest
Server logsEvery request that reached your server: people, bots, crawlers, uptime checks, link previewsHighest
Cloudflare's dashboardUnique IP addresses that requested your site, bots includedVery high
Search ConsoleClicks on your site in Google's results, whether or not the page finished loadingGoogle only, but often more than your analytics shows for Google
A cookie-free scriptBrowsers that loaded a page and ran the script, minus the bots it filters outIn the middle
A script behind a cookie bannerThe same, but only for people who clicked acceptLowest

Put those in order and you get something like the chart below. Each step down is one of the causes in the rest of this article.

How 5,000 requests become 1,400 visits

Illustration, not real data

Page requests in the server log

5,000

Bots, crawlers and uptime checks

−2,100

Requests from people

2,900

Script blocked by an ad blocker or browser

−450

Counted by a cookie-free script

2,450

Declined or ignored the cookie banner

−1,050

Counted by GA4 in basic consent mode

1,400

Made-up numbers for a small site with visitors in the EU. The order of the steps holds almost everywhere; the size of each one depends on your audience.

Bots, crawlers and other things that aren't people

A big share of the requests to any public website come from software: search engine crawlers, SEO tools, AI crawlers, uptime monitors, link previews in chat apps, and scripts trying /wp-login.php on sites that have never run WordPress. Server logs count all of it. So does Cloudflare's dashboard, which counts unique IP addresses and says plainly in its own documentation that its numbers will probably be higher than other analytics services.

Script-based tools skip most of this for free, because most bots never run JavaScript. The ones that do (headless browsers used for scraping, testing and some crawling) are what each tool's bot filter is for, and no two filters are the same. If one tool shows a burst of visits from a single country, all to the homepage, at four in the morning, with nobody staying longer than a second, that's usually a bot that got past it.

Ad blockers and privacy browsers

Content blockers like uBlock Origin ship with lists of tracking scripts, and Google Analytics is on every one of them. Brave blocks it out of the box. Plenty of privacy-focused tools end up on the same lists, so switching tools makes this smaller, not zero.

How much you lose depends almost entirely on who your visitors are. A site for developers loses far more to blockers than the site of a local bakery. No industry average will tell you yours. To measure it, compare a script-based count with something that can't be blocked, like your server log filtered down to real page requests from real browsers, for the same day.

If your site runs Google Analytics behind a cookie banner, as most European sites do, then in basic consent mode everyone who clicks reject, or ignores the banner and leaves, is invisible to it. In advanced consent mode Google sends cookieless pings for those visitors instead and, if your site is big enough to qualify, fills part of the gap with modelled estimates. So some of the users in your report were never counted. They were inferred.

How many people accept depends heavily on how the banner is designed, which is why two similar sites can show completely different numbers in GA. A tool that sets no cookies doesn't depend on the banner at all, and that alone often explains most of the gap between it and GA.

What counts as one visitor

This is the one that trips people up most, because the word is the same everywhere and the method behind it isn't.

Google Analytics recognises a returning visitor by an ID stored in a cookie. Clear your cookies, switch from phone to laptop or open a private window, and you're a new user. Safari also limits cookies set by scripts to seven days, so someone who reads your site every couple of weeks on an iPhone can arrive as a new user every single time.

Cookie-free tools do it differently. Plausible, for example, hashes the visitor's IP address and browser together with your domain and a secret salt, and deletes the salt every 24 hours. Lomen does something similar by default. The same person twice on Monday is one visitor. The same person on Monday and again on Thursday is two, because Thursday's key can't be linked back to Monday's.

Over one day, cookies and daily keys roughly agree. Over a month, they answer different questions.

A cookie-based tool counts a regular reader once for every browser it still recognises. A cookie-free one counts them once for every day they showed up. Neither is wrong, but you can't put the two monthly numbers side by side and expect them to match. (If you'd rather Lomen recognised people across days, you can opt in to a random ID in browser storage. It's off by default.)

Sessions, bounces and other words that don't travel

Even when two tools agree on visitors, the numbers below them rarely line up, because each tool defines them its own way.

GA4 ends a session after 30 minutes without activity. Its bounce rate also isn't the old “left after one page”. A session counts as engaged if it lasted longer than ten seconds, viewed at least two pages or triggered a key event, and bounce rate is the share of sessions that weren't engaged. A tool that calls every single-page visit a bounce will report a very different number for the same traffic. A blog where people read one long article and close the tab looks terrible in one tool and perfectly fine in the other.

So when you compare tools, compare pageviews and visitors, and leave bounce rate out of it.

Time zones, and the day that isn't over yet

Every tool has to decide when a day starts. GA uses the time zone set on your property. Search Console uses Pacific Time, always. From Stockholm, that means Search Console's Monday starts at nine in the morning, local time, for most of the year. A launch you post at breakfast on Tuesday lands on Tuesday in one tool and Monday in the other.

Same name, different day

Times on a Stockholm clock

Monday where you are (Stockholm)

Monday

Monday in Search Console (Pacific)

Monday
Mon06:0012:0018:00Tue06:0012:0018:00Wed

Post a launch at 07:00 on Tuesday and your analytics files it under Tuesday. Search Console files the same clicks under Monday.

Most of the year the gap from Central Europe is nine hours. Around the switches to and from summer time, which Europe and the US make on different dates, it's eight.

The latest day is also unfinished in more than one way. Google says Search Console's data for today, and sometimes yesterday, is preliminary, and GA can take a day or two to process everything. Comparing yesterday across tools is the quickest way to talk yourself into a problem that doesn't exist. Compare last week instead.

Single-page apps

If your site is built with React, Next.js, Vue or similar and moves between pages without a full reload, every tool has to notice the address change on its own. Some do it automatically, some need a setting, and some leave it to you. Get it wrong one way and every visit looks like a single pageview. Get it wrong the other way, for example by keeping GA4's automatic tracking of history changes and also sending page_view events from your router, and every page counts twice.

A ten-minute check for your own site

You don't need to make the tools agree. You need to know whether the gap between them is stable.

  1. Pick a full day at least three days ago, so every tool has finished processing it.
  2. Write down pageviews and visitors from each tool for that day. Only those two.
  3. Divide one by the other. If GA shows 58% of what your cookie-free tool shows, 58% is your number.
  4. Do the same for a day a month earlier.

If the ratio is about the same both times, you're done. The tools disagree about the size of your audience but agree about its direction, and direction is what you make decisions on. If the ratio moved, something changed in between (a new banner, a deploy that dropped the script from some pages, a bot that found you), and that's worth finding.

Which number to use for what

If you want to knowUse
Is my traffic growing?One script-based tool, used consistently. Never mix two tools in one trend line.
How is Google search doing?Search Console: clicks, impressions and the queries behind them.
How much load is my server under?Server logs or your host's dashboard. Bots are load too.
How many people read this page?A script-based tool that doesn't wait for a consent banner. Treat it as a floor, because of blockers.
Did that campaign work?Whichever tool reads your UTM tags, compared with the week before.

The one mistake worth avoiding is switching tools and comparing this month in the new one with last month in the old one. You'll see a jump or a drop that is entirely the tools' doing. If you switch, run both for two weeks, note the ratio, and start the new trend line on the day you switched.


For the record, this is what Lomen counts: pageviews from browsers that run its script, including page changes in single-page apps, with known bots and copies of your snippet on other sites filtered out, and visitors by a daily anonymous key, without cookies. It won't match your server logs either, for all the reasons above. But now you know why.

Numbers you can ask questions

Lomen is one cookie-free script: sources, campaigns and AI referrals on one dashboard, and an AI that answers from your own figures. Free during the beta, no credit card.