quest_meridian_geox_geo_incrementality_ga4.exe
_
×

Meridian GeoX: Prepare a Geo Incrementality Test with GA4

Meridian GeoX needs a daily per-geo table. Here is the BigQuery query that builds it from GA4, plus the geo-granularity trap that quietly voids a test.

meridian geox incrementality bigquery ga4 attribution guide

Google announced the general availability of Meridian GeoX on September 9, 2026, its open-source geographic incrementality testing library. Over the coming days, everyone will write “what is Meridian GeoX.” This guide handles the one part that actually blocks you when you move from reading to doing: where the data comes from, and in exactly what format. Because GeoX does not run on your GA4 export as-is, and because a single geo-granularity mistake silently voids a test that cost you weeks of live spend.

One warning up front, if you followed my guide Meridian MMM: Preparing Your GA4 and BigQuery Data: the weekly query you wrote there does not work here. GeoX requires daily data and rejects weekly aggregation, the exact opposite of what MMM asks for. We will get into it, but lock that in now before you recycle any SQL.

Why geo incrementality, and why now

Incrementality has become the hot measurement topic of 2026, for a simple reason: every other method is collapsing on its own. User-level attribution is losing its signal (the end of the Privacy Sandbox, the GA4 attribution restructuring, see GA4 Attribution Changes in 2026 and Privacy Sandbox Is Dead). MMM on its own is still suspected of endogeneity bias: it correlates spend and outcomes without ever proving causality. A geo experiment is the only genuinely causal link in the set. You cut or raise spend in some areas, leave the others untouched, and measure the gap. That is randomization, not correlation.

So GeoX lands at the right moment, and Google knows it. The meridian-geox library reached stable 1.0.x in early September 2026 (v1.0.1 on September 3), it relies on JAX for vectorized computation, and it plugs into Meridian MMM to turn an experiment result into a Bayesian prior. The cost of entry for a geo test has dropped too: Google lowered its minimum experiment threshold to $5,000 in late 2025. Demand is rising, the tool is free, and the window to claim the topic is open.

What GeoX changes versus the existing options

If you have already run “matched markets” by hand in a spreadsheet, or used Meta’s GeoLift, here is what sets GeoX apart, without the needless jargon.

CriterionDIY matched marketsGeoLift (Meta)Meridian GeoX
LanguageSpreadsheet / SQLRPython / JAX
Area selectionManual pairingSynthetic controlStratified sampling
ValidationIn-sample (fit on history)Partial out-of-sampleOut-of-sample by design
Multi-cellNoLimitedNative (several treatments, one shared control)
Design before testRareYesYes, with budget estimation
Open codeN/AOpen sourceOpen source, auditable

The real value is not speed (Google claims runtimes “twice as fast,” which is its own internal benchmark, more on that below). It is discipline: GeoX forces you to design the test before running it, to estimate its statistical power, and to validate out-of-sample rather than fit a curve to the past. Native multi-cell is the second concrete strength: comparing “cut YouTube” and “double YouTube” against the same control group, in a single study, instead of three separate tests.

The three experiment types (the first decision you make)

Before any data, you pick a design. It is the first decision, and nobody explains it clearly. It determines whether you need spend data, and above all how much your test will cost.

TypeWhat you doSpend data requiredBudget consequence
HoldbackLaunch a new campaign everywhere except the control groupNoCost = the new campaign budget. You sacrifice nothing existing.
Go-darkTurn off an active campaign in the treatment groupYesCost = the revenue you deliberately give up in the dark areas.
Heavy-upIncrease the budget in the treatment groupYesCost = the extra budget invested, whose incrementality is exactly the unknown.

Holdback is the cleanest design when you launch something new: no historical spend to provide, no existing revenue to cut. Go-dark is the most convincing for proving the incrementality of a channel already in place, but it is also the most painful, because you deliberately switch off converting spend. Heavy-up measures the marginal return of one extra dollar. Keep the rule in mind: holdback needs no spend data, go-dark and heavy-up require it (so GeoX can size the budget from your campaign stats).

The pretest table: what GeoX expects exactly

This is the heart of the matter. GeoX expects a pandas DataFrame, one row per date and area pair, with just four columns in the single-cell case:

ColumnRequiredContentWhere it comes from
dateYesA day, in a continuous daily seriesGA4 (event_date)
locationYesThe targetable market areaGA4-to-Google Ads mapping (see below)
conversionsYesRaw, unattributed conversions or revenue, in a “business as usual” stateGA4 (count of purchase) or CRM
spendOptional*Media spend per areaGoogle Ads API, cost import

* spend is mandatory for a go-dark or heavy-up design and useless for a holdback. In multi-cell studies you provide one spend column per cell (spend_cell_1, spend_cell_2), with identical values when the cells modify the same campaign and different values when they test distinct tactics.

Three constraints kill half of all projects before the first run:

First, the grain is daily, full stop. GeoX rejects weekly aggregation, unlike Meridian MMM. If you show up with a weekly table, it gets rejected. This is the most common trap for people who run MMM and then GeoX back to back.

Second, the minimum history is 3*N days, where N is the test duration. A 4-week test therefore needs at least 12 weeks of pretest. If your business has strong seasonality, aim for a year or more, otherwise the counterfactual model learns poorly and introduces bias.

Third, each date and area pair appears exactly once in the pretest table, with no gaps. Zero-conversion days must be present with a zero, not missing.

The BigQuery query that builds the table

Your GA4 BigQuery export is event-level: one row per event, timestamped to the microsecond. GeoX wants the opposite, a table aggregated by day and by area. Here is the query that bridges the two, to adapt to your project. If your export is not wired up yet, start with Using the GA4 export in BigQuery; for more GA4 SQL patterns, see 10 essential BigQuery queries for GA4.

-- Raw daily conversions per GA4 region, over >= 3*N days of pre-test
WITH conv AS (
  SELECT
    PARSE_DATE('%Y%m%d', event_date) AS date,
    geo.region                        AS ga4_region,
    COUNT(*)                          AS conversions   -- raw, UNATTRIBUTED
  FROM `project.analytics_123456789.events_*`
  WHERE _TABLE_SUFFIX BETWEEN '20260601' AND '20260831'
    AND event_name = 'purchase'
    AND geo.country = 'United States'
  GROUP BY date, ga4_region
),

-- Remap the GA4 region to the targetable Google Ads area
conv_mapped AS (
  SELECT
    c.date,
    m.google_ads_geo   AS location,
    SUM(c.conversions) AS conversions
  FROM conv c
  JOIN `project.mapping.ga4_region_to_google_ads_geo` m
    ON c.ga4_region = m.ga4_region
  GROUP BY c.date, location
)

SELECT
  cm.date,
  cm.location,
  cm.conversions,
  COALESCE(s.spend, 0) AS spend
FROM conv_mapped cm
LEFT JOIN `project.ads.daily_geo_spend` s
  ON s.date = cm.date
 AND s.google_ads_geo = cm.location
ORDER BY cm.date, cm.location

Two watch-outs on this query. The COUNT(*) over event_name = 'purchase' counts raw conversions, which is what GeoX wants: do not swap it for a key event filtered by an attribution model. And the daily_geo_spend table is the fragile part: GA4 does not know your media costs. You have to pull them from elsewhere.

Pulling spend per area

For a go-dark or heavy-up design, the spend column is mandatory, and it is the weak link on the data side. Three possible sources: the Google Ads API through the pull-geo-data method, built exactly for this; a cost import if you already centralize spend (see GA4 campaign data import, which explains why your costs “go missing” in GA4); or a first-party consolidation through Google Ads Data Manager. The critical point: spend must be broken down at the same geographic grain as your conversions. Otherwise the join is wrong, and the whole test with it.

The geo trap: GA4 geo.region is not a Google Ads area

This is the real differentiator of this guide, and the mistake that voids the most tests. GA4 and Google Ads do not speak the same geography.

GA4 geolocates server-side, by IP address, and files the user into geo.region or geo.city. Google Ads targets by location of interest and presence, with its own area identifiers (the geo target constants). The two do not overlap cleanly: one GA4 region can straddle several targetable Google Ads areas, and vice versa. If you build your treatment and control groups on the GA4 grain, then configure delivery on the Google Ads grain, your areas “leak” into each other. The result: treatment delivery reaches users counted in the control. This is called spillover, and it contaminates the measurement. You think you are measuring a causal gap, you are measuring noise.

The fix is an explicit mapping table, the one called ga4_region_to_google_ads_geo in the query above. You build it once, aligning each GA4 region with the actually targetable Google Ads area that contains it, and you exclude ambiguous areas rather than splitting them by guesswork. GeoX helps here too: its API lets you force certain areas out of the test, precisely to avoid large gray zones. Check the platform setup on the Google Ads side to know which areas are actually available before you freeze your mapping.

The four rules that break a design

Beyond the grain, four data-quality rules decide whether the test is valid. Each has a concrete symptom.

No negative values. GeoX forbids metrics that can turn negative, such as net revenue after refunds. A negative value breaks the design randomization and the statistical model. Work on gross revenue or a gross purchase count, and apply a historical net-to-gross ratio after the test if refunds are material.

No ratio metrics. ROAS is not supported. GeoX wants absolute metrics: revenue, a conversion count. A ratio metric has no meaning in the counterfactual model.

Raw, unattributed conversions. Do not send conversions filtered through an attribution model. Attribution logic distorts the very causal signal the test is trying to isolate. If the notion of window and attribution filtering is fuzzy, GA4 conversion windows: which value to choose shows well what those settings do to the numbers, and therefore why you must neutralize them here.

One primary KPI per run. The library optimizes a design for a single metric. You cannot target “new buyers” and “returning buyers” at the same time. Pick the primary KPI, size the test on it, and only analyze secondary KPIs afterward, cautiously, because their statistical power is not guaranteed.

Read the MDE and know when to walk away

At the design stage, GeoX returns an MDE, the minimum detectable effect: the smallest effect your test can reliably detect, given your budget, your areas and the duration. This is your safety rail.

The rule is simple and many ignore it: if the MDE exceeds the effect you would act on, do not run the test. Example: GeoX tells you it can only detect an effect of at least 15%, but a real incrementality of 8% would already justify a budget reallocation. Then the test teaches you nothing actionable, and you will have sacrificed spend for nothing.

If the MDE comes back too high, three levers before giving up: extend the test duration (go from 4 to 6 or 8 weeks) to accumulate volume; pick a KPI higher in the funnel (add-to-cart instead of purchase), which raises volume and cuts zero-conversion days; or widen the treatment group. If none is enough, the topic simply is not measurable at your scale, and saying so is more useful than running an underpowered test.

What it really costs

The library is free. The experiment is not. On a go-dark, the real cost is the revenue you deliberately switch off in the treatment areas for the entire test duration. Nobody should walk into a leadership meeting without that number.

You can estimate it before launching, from your own GA4 data: take the average daily revenue of the areas you plan to cut, multiply by the number of test days, and weight by the share of that revenue actually attributable to the channel being cut (the rest will keep coming through other channels). It is a range, not a certainty, but it turns an abstract conversation into a quantified decision. A 4-week go-dark on areas worth $200,000 in monthly revenue is not the same trade-off as a holdback that cuts nothing.

Closing the loop: calibrating Meridian

The value of a GeoX test does not stop at the raw result. Its measured incrementality becomes a Bayesian prior that calibrates your MMM. In practice, you inject the causal ROI measured by GeoX as a constraint in Meridian, which re-anchors the model’s estimates on ground truth rather than mere correlation. This is exactly the loop described in Meridian MMM: Preparing Your GA4 and BigQuery Data: the MMM flags the channels worth testing, GeoX tests them, and the result recalibrates the MMM. The two feed each other.

On the reporting side, the analysis outputs (counterfactual modeling, time-based regression) sit naturally in a dashboard. If you already export your data to a BI tool, Exporting your BigQuery data to Power BI, Tableau and Looker covers the possible paths.

The critical angle, in two paragraphs

Let us be clear-eyed about what you are installing. You are measuring Google media, with a library written by Google, whose prior-calibration module is provided by Google. The structural conflict of interest is real, and it deserves to be named without turning it into an indictment: a vendor measuring its own incrementality is never a neutral third party, and the modeling choices baked in have consequences for budget allocation, which flows back to Google.

The counterpart is just as real, and it is the true difference from the market’s closed measurement tools: the code is open and auditable. You, or your data team, can inspect the methodology, understand the stratified sampling and the time-based regression, and challenge the assumptions. That is not a guarantee of neutrality, it is a possibility of verification, which vendor black boxes never allow. It is up to you to take advantage of it.

Should you run this test? Five boxes to tick

Before diving in, honestly check these five points. If one is missing, the test is probably not for you, and that is an acceptable answer.

  1. You have several usable, comparable geographic areas, not a single dominant region.
  2. You hold at least 3*N days of daily per-area conversion history, with no gaps.
  3. You can pull media costs at the geo grain (if go-dark or heavy-up).
  4. The MDE returned by the design is smaller than the effect that would trigger a decision on your side.
  5. Your leadership accepts the real cost of the test (revenue sacrificed on a go-dark, extra budget on a heavy-up).

If all five boxes are ticked, you have a real causal test within reach, and the only reliable link to decide where attribution and MMM stay silent. If not, keep GeoX in reserve: the tool is not going anywhere, but your data maturity can move.