Most GA4 frustration traces back to a single unexamined assumption: that GA4 is an analytics report suite that Google made worse. It is not. It is an event stream with a reporting layer bolted on top, and almost every complaint about it is really a complaint that it will not behave like the session-based tool it replaced.
Once you stop asking it to be Universal Analytics, the setup collapses from "configure everything" to about four decisions. This post is those four decisions — plus one specific misconfiguration that is currently causing SEO teams to systematically undercount their own results.
Start here: your Organic Search number is wrong
This is the most consequential thing in the article, so it goes first rather than buried in a section about channel groups.
When someone asks ChatGPT a question, gets your page cited, and clicks through — where does that session land in GA4?
Not in Organic Search. GA4's default channel grouping identifies organic search by matching the referrer against a known list of search engines. That list was built for search engines. `chatgpt.com`, `perplexity.ai`, `claude.ai`, `copilot.microsoft.com` and the rest are not on it. So those sessions land in Referral — or, when the assistant strips the referrer entirely, in Direct.
The fix is a custom channel group. Admin → Data display → Channel groups → create a new group, and add a channel above the defaults that matches assistant sources on the referrer or source dimension:
Channel name: AI Assistants
Condition: Source matches regex
chatgpt\.com|openai\.com|perplexity\.ai|claude\.ai|
copilot\.microsoft\.com|gemini\.google\.com|
bing\.com/chat|you\.com|poe\.com
Order: ABOVE Organic Search and Referral
(GA4 evaluates channels top-down, first match wins —
if it sits below Referral it will never fire)Two caveats worth knowing before you present the number. Custom channel groups reprocess historical data in most reports, so you get backdated insight for free — a rare gift in GA4. But they do not recover the sessions that arrived with no referrer at all; those are in Direct permanently and cannot be reclassified after the fact. So treat this channel as a floor, not a total. The real figure is higher and you cannot know by how much.
Maintain the regex. It will need a new entry roughly every quarter — this list is not stable and a channel group that silently stops matching is worse than no channel group, because it looks like a decline.
Decision 1: configure backwards from three questions
GA4 will let you track anything, which is exactly the problem — infinite configurability plus no forcing function produces a property with 40 events, six of which anyone has ever looked at. The discipline is to configure backwards from the only questions an SEO team actually answers with it:
- Did the traffic arrive? — and from where, honestly attributed.
- Did it do the thing? — the one action that maps to money.
- Would it come back? — is this traffic a one-off or an audience.
Anything that does not serve one of those three is noise you are paying for in maintenance and confusion. Not "nice to have" — noise. Every extra event is a thing that can break silently, a row in a report someone will misread, and a reason your key events list is too long to scan.
Practically: pick one key event that represents value. One. Not seven. If everything is a conversion, your conversion rate is meaningless and every channel looks equally good, which is the same as having no data.
Decision 2: understand what a session is now, or stop using the word
GA4 sessions are not Universal Analytics sessions, and the differences produce numbers that look like bugs:
- No campaign-change session restart. In UA, a mid-visit campaign change started a new session. GA4 does not do this. Your session counts are legitimately lower and the old ones were arguably wrong.
- Sessions are stitched from `session_start` events, which means an ad blocker, a consent refusal or a JavaScript error does not just lose you a pageview — it loses the *entire session*. It never existed.
- Engaged sessions (10+ seconds, or 2+ pageviews, or a key event) are the useful unit, and "engagement rate" is not the inverse of the old bounce rate no matter how often it is described that way.
- Late-arriving hits get attributed to the session that was open, so day boundaries are fuzzy in a way daily reporting hides.
Decision 3: learn the four unit mismatches once
A large share of analytics meetings are spent re-litigating why two numbers disagree. They disagree because they are different units. Teach this table once and the argument stops permanently:
| Unit | Where it lives | What it counts | Why it will not match the next row |
|---|---|---|---|
| Impression | Search Console | Your result was present on a SERP. | Presence, not attention. Below-fold impressions count fully. |
| Click | Search Console | A user clicked through, deduplicated per search. | Measured at Google. Never touches your site, so nothing on your site can lose it. |
| Session | GA4 | A visit, stitched from events fired on your page. | Requires your JS to run. Consent, blockers and errors delete it. One click can be many sessions; one session can be many clicks. |
| User | GA4 | A cookie, mostly. | Cross-device, cross-browser and post-clearance the same human is several users. Consent mode makes this modelled, not counted. |
Reading down that table, the funnel from impression to user passes through four different measurement systems with four different failure modes. Expecting them to reconcile is expecting four instruments with different biases to produce the same reading. A stable gap is health. A changing gap is a bug — and it is nearly always a measurement bug, not a traffic event.
Decision 4: delete the reports and build four explorations
GA4's default reports are built for a generic e-commerce property that is not yours. The standard reports are not where the work happens; Explorations are. Build these four and ignore the rest of the left-hand nav:
| Exploration | What it answers | Build note |
|---|---|---|
| Landing page × channel | Which pages earn which traffic, with AI Assistants split out. | Free-form. Landing page as row, your custom channel group as column, sessions + key events as values. This is the single most useful view an SEO has in GA4. |
| Path exploration, backwards from the key event | What actually precedes conversion. | Start from the key event and go *backwards*. Forward paths tell you what you designed; backward paths tell you what happened, and they rarely agree. |
| Cohort by first-visit channel | Does organic traffic come back? Does assistant traffic? | This is the only view that answers question three, and it is the one nobody builds. Retention by acquisition channel is the difference between traffic and an audience. |
| Segment overlap: organic ∩ converters | Is your organic traffic the *right* traffic? | High organic sessions with near-zero overlap into converters is a content-intent problem masquerading as a success. |
The traps that waste the most time
- `(not set)` — a dimension that had no value when the event fired. Usually a tag firing before the value exists, or a dimension that does not apply to that event scope. It is a timing bug, not a data bug.
- Cardinality collapse. Too many unique values in a dimension and GA4 buckets the tail into `(other)`. Your long tail of landing pages silently merges into one useless row — the same long-tail blindness Search Console has, arriving by a different mechanism.
- Thresholding. When a report *could* identify an individual, GA4 withholds rows. Small segments simply return nothing, with a small icon as the only warning. People conclude the traffic does not exist.
- Data retention defaults to 2 or 14 months. Set it to 14 the day you create the property. Like Search Console's 16-month wall, this is not retroactive — the data you did not retain is gone.
- Reporting identity changes the numbers retroactively. Switching between Blended / Observed / Device-based re-renders history. Two people comparing screenshots from different settings will never agree, and neither is wrong.
The setup, end to end
- Create the AI Assistants channel group, ordered above Organic Search. Report it as a floor, not a total.
- Set data retention to 14 months and enable the BigQuery export. Both today. Neither is retroactive.
- Pick one key event. Delete the other six.
- Build the four explorations. Ignore the default reports entirely.
- Write the four unit mismatches on a page and send it to whoever asks why the numbers do not match. They will ask again anyway, but you will have the link.
- Re-check the assistant regex quarterly. New sources appear constantly and a stale regex reads as a decline.
None of this makes GA4 pleasant. It makes it honest, which is more useful — and it stops you reporting a number for your own channel that is wrong by a margin that grows every quarter.
If you want the assistant-traffic side of this from the other direction — not the sessions that arrive, but whether you are being cited at all — that is what AI visibility tracking measures, and the two together are the only complete picture of the channel currently available. GA4 tells you who arrived; it cannot tell you how often you were mentioned and not clicked. That number is larger, and it is increasingly the one that matters.