Of all the analytics audits we have done, we have yet to find a perfect GA4 installation. Not one. What we usually find: duplicated events inflating the metrics, a misconfigured consent mode discarding half the data, and undefined conversions — which means paid campaigns optimizing blind.
And the problem is serious: all of growth marketing rests on data. If tracking is broken, every A/B test, every budget decision, and every dashboard built on top is contaminated. In this guide we explain how to implement GA4 properly: the event model, what to measure, how to set it up with Google Tag Manager, and the mistakes we see repeated in almost every account.
Why most GA4 installations are broken
Three causes explain 90% of the disasters we audit:
- Duplicated data. The classic combination: the gtag.js snippet pasted into the template while GA4 also fires from Google Tag Manager. Result: two
page_viewevents per page, double conversions, and ratios that do not match the business. It also happens with CMS plugins that “already include analytics” coexisting with the manual tag. - Consent mode misconfigured (or missing). Since March 2024, consent mode v2 is mandatory to use Google audiences and remarketing in the EEA. We see it implemented badly all the time: either the cookie banner blocks GA4 entirely (total data loss for everyone who declines), or the opposite — everything fires without waiting for consent (a legal problem).
- Undefined conversions. GA4 does not know what matters to your business. If nobody marks events as conversions (key events), Google Ads optimizes toward clicks, reports answer no business questions, and “having analytics” amounts to having a visit counter.
The good news: none of this is hard to fix. What is hard is detecting it, because broken tracking produces numbers that look just as pretty as healthy tracking.
The GA4 event model: forget Universal Analytics categories
If you come from Universal Analytics, the first step is to unlearn. UA had different hit types (pageviews, events with category/action/label, transactions). In GA4 everything is an event with parameters:
event: sign_up
parameters: { method: "google", plan: "free" }
This has two practical implications:
- Do not stuff information into the event name.
click_green_button_homeis an anti-pattern; the right approach is a generic event (cta_click) with parameters (location: "home",cta_text: "..."). Fewer events, more parameters. - Custom parameters do not appear in reports by magic. You have to register them as custom dimensions or metrics in the property. It is the most common oversight: parameter-rich events nobody can query.
GA4 also ships with automatic events (page_view, session_start) and enhanced measurement events (scroll, outbound click, file_download, video_start…). Review them before creating your own: do not track by hand what already comes built in.
What to measure: a measurement plan tied to the funnel
The root mistake is usually not technical but a design one: measuring without a plan. Our starting point is always the same: one well-defined event per stage of the AARRR funnel.
| Stage | Example event (B2B SaaS) | Key parameters |
|---|---|---|
| Acquisition | generate_lead / sign_up | method, channel (UTM) |
| Activation | onboarding_complete, first value action | steps_completed, time_to_value |
| Retention | recurring feature_used | feature_name |
| Revenue | purchase / subscribe | value, currency, plan |
| Referral | invite_sent, share | method |
The measurement plan is a document (a spreadsheet is enough) with: event name, when it fires, parameters, who consumes it, and for which decision. If an event has no answer to “which decision does it feed?”, it does not get implemented. Ten documented events are worth more than a hundred improvised ones.
Implementation with Google Tag Manager
Our default recommendation: a single entry point (GTM) and a well-populated dataLayer. No hardcoded gtag.js coexisting with the container.
- The dataLayer is the contract between development and marketing. The product team pushes events with their parameters (
dataLayer.push({event: "sign_up", method: "google"})) and GTM translates them into tags. That way tracking survives redesigns: it does not depend on CSS classes or fragile selectors. - Naming conventions from day one:
snake_casealways (GA4 is case-sensitive:sign_upandSign_Upare two different events), English verbs consistent with Google’s recommended events (sign_up,purchase,generate_lead), and prefixes for custom events if it helps (sw_for your own events). Documented in the measurement plan. - Environments and versions: GTM lets you test in preview, publish with versions, and roll back. Use it. An untested tracking change is a data incident waiting for a date.
Conversions and audiences
With events flowing, two steps remain that almost nobody takes:
- Mark as conversions (key events) only what is business: lead, sign-up, purchase, demo request. Marking
scrollorpage_viewas a conversion destroys the usefulness of the data and confuses Google Ads. Between 3 and 5 well-chosen conversions is the norm. - Build audiences on behavior: users who activated but did not pay, abandoned carts, pricing-page visitors with no conversion. Exported to Google Ads, they turn your analytics into remarketing and similar-audience muscle. It is the part of GA4 that pays the bill.
Consent mode v2 and data loss
With consent mode v2 properly implemented, when a user declines cookies GA4 sends anonymous pings (cookieless) instead of sending nothing. From those, Google applies behavioral and conversion modeling: it statistically estimates the data of those who declined, based on the patterns of those who accepted.
What you have to accept: you will lose granularity no matter what. With rejection rates of 20-40% common in Europe, your absolute numbers are partially modeled. The practical implications:
- Configure consent mode in advanced mode (anonymous pings), not basic mode (total blocking), if you want modeling to work.
- Treat GA4 as a directional tool: reliable trends and comparisons, approximate absolute figures.
- The source of truth for business (sales, leads) should be your backend or CRM, never the analytics tool.
When to take the next step: server-side and product analytics
A well-built client-side GA4 covers a lot, but it has a ceiling:
- Server-side tracking (GTM Server-Side): makes sense when ad blockers and ITP eat a meaningful share of your data and your paid investment justifies recovering it, or when you want to enrich events with backend data and control what gets shared with each platform. It is infrastructure: it requires engineering, not just configuration.
- A product analytics tool (PostHog, Mixpanel, Amplitude): when the questions stop being marketing questions (“which channel converts?”) and become product questions (“what do retained users do that churned users don’t?”). Flexible cohorts, ad hoc funnels, session replay, and feature flags — territory GA4 does not reach.
The usual combination in companies with a digital product: GA4 for marketing and campaigns + a product tool for behavior. If you are at that point, it is exactly what we build in our data & analytics service.
GA4 audit checklist
Before signing off on your tracking:
- A single firing point (GTM or gtag, not both) and no duplicated
page_viewin DebugView - Documented measurement plan: events, parameters, owner, and the decision they feed
- Consistent naming convention (
snake_case, Google’s recommended events where they exist) - Custom parameters registered as custom dimensions/metrics
- Conversions (key events) defined: business events only, between 3 and 5
- Consent mode v2 in advanced mode, verified with the banner both accepting and declining
- Data retention raised from 2 to 14 months (it defaults to 2)
- Internal and development traffic filtered out
- Google Ads and Search Console links active
- Verification in DebugView and Realtime after every GTM publish
Common mistakes (and how to avoid them)
| Mistake | Consequence | Fix |
|---|---|---|
| gtag + GTM firing at the same time | Duplicated events and conversions | One entry point, verify in DebugView |
| Basic or missing consent mode | 20-40% data loss with no modeling | Advanced consent mode v2 with your CMP |
| Everything marked as a conversion | Google Ads optimizes toward noise | 3-5 real business key events |
| Information in the event name | Hundreds of unanalyzable events | Generic events + parameters |
| Unregistered parameters | Data sent but invisible in reports | Custom dimensions in the property |
| Data retention at 2 months | Historical analysis impossible in Explore | Raise it to 14 months on day one |
| Tracking dependent on CSS selectors | Breaks with every redesign | dataLayer as the contract with development |
| Nobody verifies after publishing | Weeks of broken data with nobody noticing | DebugView + monthly plan review |
Conclusion
Implementing GA4 properly is not pasting a snippet: it is designing a measurement plan tied to the funnel, executing it with engineering discipline (dataLayer, conventions, versions, verification), and honestly accepting the limits of consented data. The difference between doing it well and doing it half-well is not visible on the website — it shows up three months later, when the decisions made with that data work or don’t.
And if we have learned anything from auditing accounts: it is far cheaper to build tracking right once than to make decisions on broken data for six months.
Suspect your GA4 is measuring things wrong? We audit it and tune it up →