
You can’t run an A/B test inside Google Analytics 4. GA4 has no tool for splitting traffic or serving variants, and Google Optimize, which used to do that job, was shut down in September 2023. What works now is a two-part setup: a testing tool assigns visitors to variants and serves the change, and GA4 receives the variant name as an event parameter or user property, so you can compare variants against your key events in Explorations.
Below is that setup the way we build it for clients, plus the mistakes that quietly invalidate results.
Can you still A/B test with Google Analytics 4?
Yes, but GA4 is the measuring tape, not the experiment. Many older guides (including an earlier version of this one) describe GA4 testing features that don’t exist, so here is the real split.
| Job | GA4 | Testing tool |
|---|---|---|
| Split traffic into variants | No | Yes |
| Serve the changed page, copy or feature | No | Yes |
| Keep a visitor in the same variant across visits | No | Yes (cookie, user ID or server-side assignment) |
| Record which variant a visitor saw | Yes, if you send it | Yes |
| Measure key events, funnels and revenue per variant | Yes | Usually, for the goals you define in it |
| Calculate statistical significance | No | Usually |
| Join test data with traffic source, device and behavior | Yes | Partly |
GA4 earns its place because it already holds the rest of your measurement: traffic sources, the full funnel, and lead and ecommerce events. Reading a test there shows whether a variant that won on clicks lost on qualified leads.
Mobile apps still have a Google-native route: Firebase A/B Testing, which works with Remote Config and Analytics events.
Which testing tool should you pair with GA4?
Pick the tool by where the change lives: a copy test on a marketing page and a pricing change inside a product need different machinery.
| Type of tool | Good for | Watch out for |
|---|---|---|
| Visual, client-side editors (for example VWO, Optimizely Web, AB Tasty, Convert) | Headlines, layouts, CTAs and forms on marketing pages, without a developer for every test | Flicker as the original page loads before the variant; page-speed cost of the script |
| Feature flags and server-side experiments (for example PostHog, GrowthBook, LaunchDarkly, Optimizely Feature Experimentation) | Pricing, onboarding steps, product features, anything rendered by your app | Needs developer time; you must pass the variant to GA4 yourself |
| Warehouse-native analysis (for example GrowthBook on top of the GA4 BigQuery export) | Teams already working in BigQuery that want their own statistics | Needs SQL skills and a clean export |
| Firebase A/B Testing | iOS and Android apps | Apps only |
Many offer a ready-made GA4 integration. Check what it sends before you trust it: event and parameter names, and whether it fires once per visitor or on every page.
How do you send the experiment and variant to GA4?
Send one event when a visitor is first exposed to the test, carrying the experiment and the variant as parameters. Then register those parameters as custom dimensions so they show up in reports and Explorations.
There are two common ways to store the variant, and we often use both:
- An exposure event with parameters. For example an event called
experiment_impressionwithexperiment_idandvariant_id. This tells you exactly when someone entered the test. Some vendor integrations use Google’s own suggested naming (experience_impressionwith anexp_variant_stringparameter); either works as long as you are consistent. - A user property. For example
ab_variantset tohomepage_hero_B. A user-scoped value sticks to later events from the same user, which makes it easier to tie the variant to a conversion that happens days later.
A typical Google Tag Manager setup looks like this:
- The testing tool pushes the assignment into the data layer, for example
dataLayer.push({event: 'experiment_impression', experiment_id: 'pricing_page_q4', variant_id: 'B'}). Most tools have a setting or callback for this. - In Google Tag Manager, create Data Layer Variables for
experiment_idandvariant_id, and a Custom Event trigger onexperiment_impression. - Add a GA4 Event tag that sends
experiment_impressionwith both parameters, and, if you want the user-scoped version, sets the user property too. - In GA4, go to Admin, then Custom definitions, and register
experiment_idandvariant_idas event-scoped custom dimensions (andab_variantas a user-scoped one). - Check it in DebugView before the test goes live.
Step 4 has to happen before launch. GA4 custom dimensions are not retroactive: data collected before you register a parameter won’t appear in reports under that dimension later. If a test is already running, register now and start your analysis window from today.
Name experiments so they make sense a year later: pricing_page_annual_toggle_2026q4 beats test3. For the basics of events and parameters, see our guide to GA4 event tracking.
How do you compare variants in GA4 Explorations?
Build a free-form exploration with the variant as a dimension or as segments, and your key events as metrics. That gives you a side-by-side table you can trust more than any one-off screenshot.
- In Explore, start a blank free-form exploration and set the date range to the test window only.
- Create one segment per variant. A user segment (“users who triggered
experiment_impressionwherevariant_id= A”) is usually the right choice, because a conversion often happens in a later session than the exposure. - Add metrics: active users, the key events that decide the test (event count or key events for that event), and ecommerce purchases or revenue if you sell online.
- Add breakdown dimensions such as device category or session default channel group to see whether a variant wins everywhere or only on, say, mobile paid traffic.
- For multi-step journeys, a funnel exploration with the same variant segments shows where each variant loses people.
Watch for sampling on large date ranges and for data thresholds hiding small rows. When a test matters, we calculate the result from the BigQuery export instead. Our Explorations masterclass goes deeper into segments and funnels.
Which key events should decide the test?
Decide before launch and write it down: one primary metric picks the winner, and two or three guardrails make sure the win isn’t hurting something else.
- Primary: the key event closest to revenue that still gets enough volume, such as a form submission, a trial signup or a purchase. GA4 renamed conversions to “key events” in 2024; you mark them in Admin, under Events.
- Guardrails: revenue per user, lead quality (if your CRM sends qualified-lead or closed-won data back), and page performance.
The lead-generation trap: more form fills can mean worse leads. Where you can, send qualified-lead status back from the CRM with the GA4 Measurement Protocol (see offline conversions from CRM data) and judge the test on that.
How much traffic and time does a test need?
Enough visitors to detect the size of change you care about, and at least one full business cycle, usually whole weeks. Calculate this before launch rather than stopping when the chart looks good.
Sample size depends on three things: your baseline conversion rate, the smallest lift worth detecting, and how sure you want to be. A common rule of thumb for 95% confidence and 80% power is:
n per variant ≈ 16 × p × (1 − p) / d²
where p is the baseline conversion rate and d is the absolute difference you want to detect. As a worked example with made-up inputs: at a 2% baseline, detecting a move to 2.5% (d = 0.005) needs about 16 × 0.02 × 0.98 / 0.000025, or roughly 12,500 visitors per variant. Halve the lift you want to detect and you need about four times the traffic.
That is why low-traffic B2B sites should test big changes (an offer, a page structure, a form) rather than button colors. Run in whole weeks, and avoid launching into a sale, a holiday or a big campaign change.
What breaks GA4 A/B test results?
Most bad test results we audit come from the setup, not the statistics. These are the usual suspects.
| Problem | What it looks like | Fix |
|---|---|---|
| Sample ratio mismatch (SRM) | A 50/50 test shows 54/46 users in GA4 | Check with a chi-square test; investigate redirects, bots, consent and tag firing before reading any result |
| Peeking | Stopping the day the result turns “significant” | Fix the sample size and end date in advance |
| Exposure event fires on every page | Event counts far above user counts | Fire once per assignment, or analyze by users |
| Flicker | Visitors briefly see the original, then the variant | Use the tool’s anti-flicker snippet carefully, or move to server-side assignment |
| Dimension registered late | Early test days missing from reports | Register custom dimensions before launch |
| Novelty effect | Strong first week, fading after | Run long enough to see the curve flatten |
| Cross-device users | Same person counted in both variants | Use a user ID where people log in; accept some noise elsewhere |
If the split is off, something treats one variant differently, and the “result” may just be that bug. Find the cause before reading anything.
How does consent mode change the numbers?
In regions where you need cookie consent, GA4 only measures fully the visitors who accept analytics storage. With Consent Mode in its basic form, visitors who decline send nothing; in advanced mode, they send cookieless pings that GA4 uses for modeling.
Two effects follow. GA4 will count fewer people than the testing tool, which is expected: compare variants within GA4, not GA4 against the tool. And if a variant changes how the consent banner appears, it changes who gets measured, so keep the banner identical across variants.
The testing tool also stores an identifier, so check whether it needs consent too. Server-side tagging helps with data quality here; our server-side Google Tag Manager guide explains how, and GA4 and data privacy covers the consent side.
What have we learned from testing for clients?
The biggest wins come from testing the message, not the button.
For ATC Alert, a medical alert company, we tested ad messaging round by round, through variant G. The early variants led with price and the low one-time equipment fee for the watch; the tests moved the messaging to the subscription and the 24/7 service behind it. In parallel we moved tracking server-side, so Google and Meta received reliable conversion data to judge each variant by.
For Hemptouch, a hemp skincare brand that can’t advertise on Google or Facebook, the lesson was about order. We fixed the analytics first, which showed where readers dropped off, then redesigned the most-read blog posts to work as landing pages. The conversion rate went from 0.5% to 2% in six months. That was an iterative redesign, not one split test, and it worked because the measurement was right first.
If your GA4 setup isn’t ready to tell you which variant won, start there. Our GA4 service and wider analytics work begin with exactly that audit.
FAQ
Does GA4 have a built-in A/B testing feature?
No. GA4 has no way to split traffic or serve variants, and it doesn’t calculate significance. Google Optimize, which did, was discontinued in September 2023. Use a testing tool for the experiment and GA4 to measure it.
What replaced Google Optimize?
No single product. Teams use third-party testing tools, many of which offer GA4 integrations, or feature-flag platforms for server-side tests. For apps, Firebase A/B Testing remains available.
Should the variant be an event parameter or a user property?
Use an event parameter on an exposure event to record when someone entered the test, and add a user property if conversions often happen in later sessions. Register both as custom dimensions before launch.
How long should an A/B test run?
Until it reaches the sample size you calculated in advance, in whole weeks. Two weeks is a common minimum; low-traffic sites often need longer, or a bolder change.
Why do GA4 and my testing tool show different numbers?
They count differently. Consent choices, ad blockers, bot filtering and session rules all differ. Compare variants within one system, and investigate only if the split between variants itself looks wrong.


