To set up Google Analytics 4 the right way, write a tracking specification first, create one property with 14-month retention, load Consent Mode v2 before any tag, track one event per action category with parameters, route revenue events through server-side Tag Manager where paid media depends on them, check the AI Assistant channel, and link BigQuery on day one.
A common pattern shows up in Google Analytics 4 (GA4) audits. A team set up GA4 in 2023 or 2024 from a blog tutorial, fired the base tags and never came back. By 2026 the data is wrong in ways nobody can explain: conversion counts that do not match the CRM, Direct traffic that quietly absorbed ChatGPT and Perplexity referrals, consent banners that look compliant but leak data, and a BigQuery export that was never connected.
Setting up GA4 from scratch in 2026 is a different job than it was even a year ago. Consent Mode v2 is required for advertisers reaching users in the EEA. Server-side Google Tag Manager has moved from nice-to-have to the most reliable way to recover conversions that Safari ITP and ad blockers silently drop. And in May 2026 Google added a native AI Assistant channel to GA4, separating ChatGPT, Gemini and Claude traffic from generic referrals.
This is the build order the Waftr team uses on greenfield GA4 implementations. It assumes nothing exists yet. By the end, the setup is auditable, consent-aware, server-side ready, AI-traffic aware and exporting to BigQuery from day one.
Start with a tracking specification, not tags
A correct GA4 implementation starts with a written tracking specification before any tag fires. Skipping it is the most common cause of broken GA4 setups.
The specification defines every event and parameter, its data type, the expected values, where it fires and which user journey it belongs to. Treat it like code: keep it in a Google Sheet or a versioned file in the engineering repo, and require a review for every change.
The cost of skipping it shows up later. A property that has been live for a year often carries dozens of event names, many of them typos, abandoned tests or duplicates, while the events that matter use different parameter names on different pages, so reports average empty values with real ones. Cleaning that up takes weeks. The specification that prevents it takes days.
Four questions every event must answer
- 1What triggers it?
- 2What data does it carry?
- 3Who depends on the report it feeds?
- 4What happens if it stops firing?
If those four cannot be answered, the event does not get implemented.
How should you create the GA4 property and data stream?
One GA4 property per business, one web data stream per domain, and data retention set to 14 months on day one. Do not split a single product across multiple properties.
- Properties
- One per business
- Web data streams
- One per domain
- Data retention
- 14 months
- Cross-domain measurement
- Configured on the stream
- Enhanced measurement
- Only what the spec lists
- Internal traffic filter
- Active before launch
GA4's default data retention for Explore reports is 2 months. Nobody changes it until they need a year-over-year exploration and discover the data is gone. Set it to 14 months immediately, under Admin, Data retention.
Use a single web data stream per domain. Subdomains belong on the same stream unless they are a separate business. Configure cross-domain measurement on the stream instead of duplicating properties: two properties for one product create two data sets nobody can join without BigQuery work.
Turn on enhanced measurement only for the events the specification lists: page views, scrolls, outbound clicks, site search, video engagement and file downloads. It is helpful by default and noisy at scale.
Define internal traffic before the property goes live: office and VPN IP ranges, plus the development subdomain. QA traffic left in the property pads the funnel for months before anyone notices it.
The 2026 GA4 architecture
A correct 2026 GA4 setup runs through six layers: the browser, the dataLayer with the consent management platform, the GTM web container, the server-side GTM container, the GA4 property and the BigQuery export.
- 01BrowserFires every page view, click and form submit.
- 02dataLayer and CMPStructured events, with consent defaults set first.
- 03GTM web containerApplies consent state and forwards events.
- 04Server-side GTMEnriches, strips personal data, routes to each endpoint.
- 05GA4 propertyProcesses events into reports and audiences.
- 06BigQuery exportRaw, unsampled events in daily tables.
Each layer does one job. The browser fires user actions. The dataLayer captures them as structured events. The GTM web container reads the dataLayer, applies the consent state and forwards events to the server container. The server container enriches, filters and routes events to GA4 and other destinations. GA4 processes the data and writes raw events to BigQuery every day.
The CMP is the first thing that loads. It sets the default consent state before any tag can fire. The Google tag in the web container then passes the consent state to the server container in the gcs and gcd parameters, and server-side tags read them and behave accordingly.
The server container strips personal data before it reaches Google and routes events to GA4, Google Ads, Meta CAPI and other endpoints. That gives a team three things a default setup cannot: durable first-party identifiers, full control over personal data before it reaches Google, and a recoverable signal when the browser blocks third-party requests.
Wire Consent Mode v2 before you send a single event
Consent Mode v2 must be configured with a default-denied state before any GA4 tag can fire. If a tag fires before the consent default loads, the banner is decorative and the data is non-compliant.
ad_storageDefault: deniedGranted on Acceptanalytics_storageDefault: deniedGranted on Acceptad_user_dataDefault: deniedGranted on Acceptad_personalizationDefault: deniedGranted on Accept
Three pieces have to be in place:
- A consent management platform that integrates with Consent Mode v2, such as Cookiebot or OneTrust. Google requires a Google-certified CMP for publishers serving Google ads in the EEA and UK, and a certified CMP is the safer route for advertisers too.
- Default consent set to denied for ad_storage, analytics_storage, ad_user_data and ad_personalization.
- An update command that fires when the visitor makes a choice.
Load order matters. The CMP loads first and sets the default state, and only then does Tag Manager evaluate tags. Most broken setups load Tag Manager before the CMP, so consent is granted by accident and the banner does nothing.
A frequent audit finding: the CMP fires on every page, but the GA4 tag is set to fire without a consent check, so sessions are recorded for visitors who declined cookies. The fix takes minutes. The legal exposure builds for months.
Send the consent state to the server container too. If Meta, TikTok or Pinterest tags fire server-side, wire them to read the same consent state. Most teams wire consent for Google tags only and let everything else fire regardless, which is the first gap a cookie consent implementation should close. The NexTranslate consent case shows the target state: 100% of tags waiting for consent, verified by test.
Once consent is live, expect Google Ads and GA4 to drift apart. Google Ads can model conversions from visitors who declined, while GA4 shows modeled data only when the property qualifies, so a higher denial rate widens the gap. The guide on why Google Ads and GA4 report different conversions has a quick test for it.
A 60-second consent testIf the banner asks for a choice but GA4 cookies are already set, the consent flow is broken. Open DevTools, hard-reload with the cache disabled, and watch which cookies appear before you click Accept. There should be none.
Build the event model around one core pattern
Instead of inventing an event for every button, track one core event per category and attach parameters for the variation. The pattern scales, and it keeps you inside GA4's collection limits: a standard property allows 50 event-scoped custom dimensions, and each event carries up to 25 parameters.
Event explosion
- cta_homepage_hero
- cta_homepage_footer
- cta_pricing_top
- cta_pricing_bottom
One core event
- cta_click
- cta_location
- cta_destination
- cta_label
The common failure is the event explosion: cta_homepage_hero, cta_homepage_footer, cta_pricing_top, cta_pricing_bottom and twenty more. Reports fill with overlapping events that nobody can compare without manual work.
The clean pattern is one event, cta_click, with three parameters: cta_location, cta_destination and cta_label. Reports can then filter and segment by any combination, the event count stays small, and the custom dimensions stay readable.
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'cta_click',
cta_location: 'pricing_page_hero',
cta_destination: '/signup',
cta_label: 'Start free trial'
});For ecommerce, use Google's recommended event names exactly as written: view_item, add_to_cart, begin_checkout and purchase. They map automatically to GA4's monetization reports, and renaming them breaks the reports that depend on them.
Register every custom dimension and metric under Admin, Custom definitions, before the event goes live. A parameter that is not registered never appears in reports, and registration is not retroactive.
When should you move to server-side tagging?
Move an event server-side when it carries personal data, drives revenue reporting or ad bidding, or is materially affected by Safari ITP and ad blockers. For everything else, client-side Tag Manager is still fine.
- Check 1Does the event carry personal data, such as an email, a phone number or a hashed user ID?Server-sideStrip or hash it before it reaches Google.
- Check 2Does it feed revenue reporting or Google Ads bidding?Server-sideLost signal here costs real budget.
- Check 3Is it materially affected by ITP, ad blockers or browser tracking limits?Server-sideThe only way to recover that signal.
- Client-side GTM is fine. Most engagement, scroll and content interaction events can stay in the browser.
The shift is real. Browsers and ad blockers drop a share of client-side GA4 and ad events before they reach Google, and for a business with paid acquisition, that lost signal decides whether bidding has enough conversions to learn from. In one US retail project, server-side tracking with server-set cookies and Consent Mode v2 moved leads out of direct into their real sources and cut cost per lead 20%.
There are three practical ways to host the server container. Google Cloud Run is usually the lowest-cost option for teams comfortable with Google Cloud. Stape is a managed server-side GTM host that handles scaling, SSL and monitoring for teams without infrastructure staff. Self-hosting on AWS or Azure works, but adds operational work most teams do not need.
The most common mistake on a new server container is leaving verbose logging on. Logs get read once a quarter and paid for every day, so switch logging to errors only once validation ends.
What changed with the AI Assistant channel in May 2026?
On May 13, 2026, Google added a native AI Assistant channel to GA4. Sessions referred by recognized AI assistants, including ChatGPT, Gemini and Claude, are now classified automatically from the referrer, with no configuration on your side.
- Organic Search
- Direct
- Referral
- AI AssistantNew
- Paid Search
Until then, AI assistant traffic landed in Referral or, when the referrer was stripped, in Direct, and teams had to build regex channel groups by hand. Now three things happen at once: the Medium dimension gets an ai-assistant value, the default channel group shows an AI Assistant channel in Acquisition reports, and Campaign name receives an (ai-assistant) value.
Three caveats matter:
- The classification needs a referrer. A session without one still lands in Direct.
- Google maintains the list of recognized assistants. A tool that is not on it still needs a custom channel group to stand on its own.
- History is not reclassified. Past AI sessions stay in Direct or Referral, wherever they originally landed.
For teams doing answer engine optimization, this is the cleanest AI traffic signal Google has shipped. Build an Explore that compares the AI Assistant channel with organic search to see whether content starts converting through AI surfaces. Our guide on how to check AI traffic in GA4 covers the native channel and the regex method for older months.
Connect BigQuery on day one
Link GA4 to BigQuery the day the property is created. The export starts on the day you link it and does not backfill earlier events, and a team that waits for its first raw-data question finds nothing to query. Explore reports sample once a query passes 10 million events on a standard property, and Explore can only reach back as far as your retention setting. The BigQuery export has neither limit.
The daily export carries no GA4 fee: you pay BigQuery storage and query costs, and many smaller properties stay inside BigQuery's free monthly tier. Standard properties can export up to 1 million events a day. Streaming export adds cost and is rarely worth it for SaaS or content sites, where daily is enough for almost every analysis.
Set it up under Admin, Product links, BigQuery links. Choose the Google Cloud project, the data location and a Daily frequency. GA4 then writes raw events into a dataset of daily tables named events_YYYYMMDD.
Three things only the raw export gives youUnsampled data at any volume; joins against the CRM, the warehouse and product analytics on user_id or client ID; and retention for as long as you keep the tables.
Where a property exports to BigQuery, Waftr's audits start there. The GA4 interface is a smoothed, sampled view of what happened. BigQuery is what happened.

