Six months after launching GA4, you open the report and notice something off. (not set) rates are climbing. The same product is firing purchase with two different parameter structures. Custom event names show up as Click_Button, click-button, and clickButton — split across three rows in the report. Has this happened to you?
I've been there. The first time I instrumented GA4 on my own product, I spent half a day six months later just figuring out why purchase was double-counting tax-inclusive and tax-exclusive revenue. The root cause was almost never technical. It was that I had blurred the boundary between GA4's three event layers from day one.
TL;DR
- GA4 events have a 3-layer structure (automatic / recommended / custom). Each layer differs in source, editability, and parameter spec — mixing them carelessly guarantees breakage later
- For e-commerce, lean on recommended events. Sending the 12 events to spec is what keeps standard reports, ecommerce reports, and BigQuery exports consistent
- Lock down naming rules and parameter design before implementation. Retrofitting "verb_noun / snake_case / no reserved prefix" later is essentially a re-design of all your measurement data
- Verification is a 3-layer process: DebugView → Realtime → BigQuery. Skip any one and you ship a system that looks instrumented but is silently broken
The 3 layers of GA4 events
GA4 events fall into three layers based on who sends them and how GA4 recognizes them.
| Layer | Source | Editable | Examples |
|---|---|---|---|
| Automatic | GA4 tag sends automatically | No |
page_view / session_start
|
| Recommended | Your site sends, Google defines spec | Name fixed |
view_item / add_to_cart / purchase
|
| Custom | Your site sends and defines | Name & params free |
click_hero_cta / scroll_50pct
|
The most important fact for e-commerce operators: most behaviors that happen on an e-commerce site are already covered by recommended events. Reserve custom events strictly for behaviors recommended events cannot express.
The 12 recommended events for e-commerce
The recommended events for an e-commerce site map to the user journey in 12 items. The most common implementation accident is the purchase event — if transaction_id is empty or duplicated, GA4's deduplication fails and revenue is double-counted. The Shopify thank-you-page case where purchase fires from both "thank you page view" and "app-side conversion tracking" is the most frequent failure I see.
But here's the thing: implementing all 12 recommended events correctly is not the goal. It's the raw material.
The real value shows up when you take the value from purchase and break it down by session, by channel, by landing page. Comparing Revenue Per Session (RPS = Revenue ÷ Sessions) for Google Organic versus Meta Ads visits exposes CVR and AOV gaps and combined investment efficiency in a single number.
Note that Revenue Per Session (RPS) is not yet a widely recognized industry metric, despite being mathematically equivalent to CVR × AOV. Most analytics tools, including GA4, do not surface it as a default metric — you have to construct it from raw event data.
Naming rules — the 3 things to lock down before implementing
The single biggest regret in my early implementation was trying to retrofit naming conventions after events were already flowing. It's essentially a re-design of all your measurement data.
The 3 rules to lock down at design stage:
-
verb_noun: action as verb (
click/view/download), object as noun (cta/whitepaper). Composeclick_hero_cta -
snake_case: underscores between words. Mixing
clickHeroCta(camelCase) orclick-hero-cta(kebab-case) splits them as separate events in GA4 reports -
Avoid reserved prefixes:
ga_/google_/firebase_are silently disabled. If you want a project-specific prefix, use a 1–2 character custom prefix likers_click_cta
Verification is 3 layers — DebugView, Realtime, BigQuery
Once you implement an event, always verify across three layers. Skip any one and you ship a system that "looks instrumented but is silently broken."
- DebugView shows what GA4 received (seconds, real-time)
- Realtime report shows what GA4 counted (minutes)
- BigQuery shows the actual stored parameter structure (1 week post-launch, via SQL)
The gap between DebugView and Realtime is where silent failures hide. Visible in DebugView but not in Realtime → reserved prefix collision likely. Visible in Realtime but not in standard reports → custom dimension not registered.
Wrapping up
GA4 custom event setup is not a technical challenge. The hard part is making the 3-layer boundary explicit at the start, locking down naming rules before implementing, and verifying across all three layers (not just one). With those four steps, your measurement foundation will survive 6 and 12 months.
Full implementation walkthrough — including reserved parameter pitfalls and BigQuery verification SQL — is at GA4 Custom Event Setup Guide.
Question for you: What was the first GA4 event you set up that you later wished you'd designed differently? Curious to hear what tripped people up — and whether the 3-layer model would've helped.




Top comments (0)