Three blind spots in your stats, and what is hiding in the gap
Google Analytics shows you the people who clicked accept. Everyone else is missing, without a trace. On top of that come two groups that did not exist in 2020: AI crawlers reading your text, and people arriving from ChatGPT or Perplexity. As of today our ad plugin counts both.
There is one number nearly every site owner knows and almost nobody questions: users over the last seven days. It sits in the report, gets passed along, ends up in proposals and media kits. And it does not describe your website's visitors, it describes a subset of them.
Blind spot 1: everyone who declined
The mechanism is simple. Analytics only loads after consent, so it only counts those who consented. Anyone declining, dismissing the banner or running a blocker leaves no trace.
On large publishers Google compensates for part of this statistically, which it calls modelling. That does not apply to small sites: below roughly a thousand events per day nothing is modelled. The gap does not become an estimate, it becomes nothing at all.
Nobody can tell you how big that gap is in general, because acceptance rates depend on audience, banner design and subject. Which is why the only sensible answer is to measure it on your own site rather than quote a study.
Blind spot 2: the machines reading along
For two years now a new group has been reading your text, and it appears in no analytics report: OpenAI's GPTBot, Anthropic's ClaudeBot, PerplexityBot, plus crawlers from Google, Microsoft, Meta, Apple, ByteDance, Amazon, Common Crawl and Mistral. They execute no JavaScript, so as far as an analytics script is concerned they do not exist.
This is more than a curiosity. If you want your content to appear in answers, the first question is whether it gets read at all, and the second is which pages. Both are answerable server-side, because these crawlers identify themselves.
Blind spot 3: visitors an AI sent you
The counterpart: people arriving from ChatGPT, Perplexity, Claude, Copilot or Gemini. Analytics does count them, but it drops them into the same bucket as a forum link, somewhere between Pinterest and an email signature.
For the question of whether content pays off with answer engines, that is precisely the interesting channel. It deserves its own line, per day and per landing page.
What Sonar does with that
Since version 2.6.0 our ad plugin carries a tab of its own closing these three gaps, plus a check that logically belongs beside them. Everything stays in your database and nothing calls out.
The counting
A script under two kilobytes runs once the page has finished loading. Because it executes in the browser, it counts pages served from a cache too, which server-side counters routinely miss.
Unique visitors come from a hash of address and browser signature, salted with a random value discarded at midnight. After that the attribution cannot be reconstructed, not by us and not retroactively. The address itself is never written down.
The crawlers
44 identifiers, detected server-side, grouped by vendor and by the pages actually fetched. A visitor who is not a crawler causes no database work at all.
The referrals
Visits from eleven AI assistants are tracked as their own channel, per day and landing page. No other referrer is stored, so no general referrer database accumulates as a side effect.
The consent check
For first-time visitors who have not decided yet, Sonar looks at whether a full analytics or pixel request went out, and names the host. Red means a full hit, yellow a cookieless Consent Mode ping, green nothing sent. Why this is such a widespread problem, and the four causes behind it, is covered in our piece on tracking before consent.
The dark figure
You enter the last seven days' user count from Google Analytics by hand, Sonar puts its own count beside it and works out the factor, along with your banner's acceptance rate. Without your input nothing is estimated. That is deliberate: a guessed dark figure would be exactly the mistake this whole tab exists to avoid.
What Sonar cannot do
Three limits, stated in the plugin next to every number and therefore stated here:
- Visitors with script blockers are missing. They are not estimated and not extrapolated. They are absent, and the tab says so at the number.
- Behind a page cache the server only sees the crawler requests that miss it. Crawler figures are a lower bound, not a complete census.
- The consent check is a check, not a watch. In the free version you see the finding in the admin. There is no permanent guard that emails you.
Also not built, however obvious it may sound: an automatic Google Analytics connection, an import from server log files, a per-page reading map. They are planned, but they do not exist, and while they do not exist they will not be described here.
Why this sits in an ad plugin
Fair question. The answer has to do with how it started: Sonar came out of a measurement in which we checked 40 websites for whether they send data before consent. Going through the results, it became clear that the actual question never gets asked, namely who was there in the first place and who is missing from the report.
Anyone serving ads needs that number anyway. An ad is shown to every visitor, including the one who declined the banner. If your reach figure comes from Analytics while the ad reaches everyone, report and reality diverge, and not in your favour.
Trying it
Sonar is part of Hafenstudios Ads from version 2.6.0, free in the WordPress directory. After activation it takes a day or two before the numbers mean anything, because counting starts when you switch it on and nothing is reconstructed retroactively.
The most honest first step is a different one, though, and it costs two minutes: check whether your site sends anything before your visitors have decided. How to do that is here.
Frequently asked questions
Why does Google Analytics report fewer visitors than actually came?
Because Analytics only counts once somebody has consented in the cookie banner. Anyone who declines, dismisses it or runs a script blocker never appears. Google does not compensate for this on small sites either: below roughly 1,000 events per day nothing is modelled. So the gap is not an estimate with some fuzziness, it is a hole. How big it is depends on your acceptance rate and ranges from a few percent to more than half, depending on audience.
How do I find out whether AI crawlers read my website?
Most reliably on the server side, from the identifier a request announces itself with. GPTBot, ClaudeBot, PerplexityBot and around forty others identify themselves. They never show up in Google Analytics because they do not execute JavaScript. One limit is worth knowing: if a cache sits in front of your site, it answers many requests without WordPress ever seeing them. Only what misses the cache gets counted.
Can you count visitors without cookies?
Yes, if you give up recognising them over time. The usual route is a short-lived marker: address and browser signature are hashed with a random salt that expires daily. That lets you attribute page views to a visitor within one day, while the next day the connection can no longer be made, not even retroactively. The address itself is never stored. No consent is needed, because nothing is placed on the visitor's device.
Does cookieless counting replace Google Analytics?
No, and it should not pretend to. What is missing are goals, user journeys, audience reports and the link to ad accounts. What it does provide is an honest baseline: how many people were actually there, next to how many appear in your report. The two numbers side by side tell you more than either alone.
What does Sonar cost?
Nothing. Since version 2.6.0 Sonar is part of Hafenstudios Ads in the WordPress plugin directory, not a separate plugin and not an add-on purchase. The data stays in your own database, with no cloud connection and no outbound calls.