Google Tag Gateway: setup, results and QA
Google tag gateway serves your Google tag from your own domain. What it is, how it differs from server-side GTM, who it suits, the results to expect, and how to set it up and QA it.
TL;DR
Google Tag Gateway for advertisers (GTG) serves your Google tag or GTM container from a path on your own domain, such as example.com/metrics/, instead of googletagmanager.com. Your CDN or load balancer forwards that path to Google, so the script and part of the measurement traffic become first-party. You can switch it on in a few clicks with Cloudflare, or configure it yourself on Google Cloud, Akamai, CloudFront, Fastly or almost any CDN.
This post covers the full journey: what GTG is, how it differs from server-side GTM, who should use it, what results to expect, every implementation route, and a QA checklist you can run before and after go-live.
What Google Tag Gateway is and how it works
GTG lets you deploy a Google tag using your own first-party infrastructure, hosted on your website's domain, through your existing CDN, load balancer or web server (Google). It is a routing layer: nothing about your tags, triggers or variables changes.
Standard setup. The page requests gtag.js or gtm.js from www.googletagmanager.com. When tags fire, measurement requests go straight to Google domains.
With GTG. The page loads the tag from a reserved path on your domain, for example https://example.com/metrics/. When tags fire, some measurement requests are also sent to Google through that first-party path (setup guide).

The only new moving part is the reserved path on your edge. Tags, triggers and Google's own endpoints stay exactly as they were.
Under the hood, your edge layer does three things for every request on the reserved path:
- Forwards it to Google's gateway endpoint,
{TAG-ID}.fps.goog(for examplegtm-abcdef.fps.goog), with theHostheader set to that endpoint. Cloudflare and Fastly variants instead callfps.googand pass the ID in anX-Gtg-Tag-Idheader. - Adds the visitor's location, because Google now sees your CDN's IP rather than the user's. That is done with
X-Forwarded-Country+X-Forwarded-Region, or a singleX-Forwarded-CountryRegionISO 3166-2 code such asGB-ENG, plus optionalX-Forwarded-Geolocationfor lat/long and city. - Passes cookies and query strings through untouched, with no caching.

Get these headers right and Google can still place each visitor correctly, even though every request now arrives from your CDN's IP.
What Google Tag Gateway is not
- Not server-side GTM. There is no server container, no client/tag logic and no data transformation. Requests are proxied, not processed.
- Not a consent workaround. Consent Mode signals and your CMP decisions apply exactly as before.
- Not a fix for non-Google tags. Meta, TikTok and other vendors still load from their own domains unless you proxy them separately.
Google Tag Gateway vs server-side GTM
GTG and server-side GTM (sGTM) solve different problems, and Google's recommended architecture uses both: the CDN serves Google scripts first-party, while a separate sGTM server handles collection, enrichment and control (Google).

The CDN takes script serving off the tagging server; sGTM keeps full control over what each event carries before it leaves your infrastructure.
| Setup | Scripts served from | Hits sent to | Data control | Extra infra | Effort |
|---|---|---|---|---|---|
| Standard Google tag | googletagmanager.com | Google domains | None | None | None |
| GTG with CDN | example.com/metrics/ | Partly via example.com/metrics/ | None (pass-through) | Your existing CDN | Low |
| sGTM on a subdomain | googletagmanager.com (unless sGTM serves them) | sst.example.com | Full: clients, transformations, enrichment | Tagging server (Cloud Run or hosted) | Medium–high |
| GTG with sGTM | Tagging server | Tagging server | Full | Tagging server handles both jobs | Medium–high |
| GTG with CDN + sGTM (recommended) | example.com/scripts/ via CDN | example.com/metrics/ via sGTM | Full | CDN + tagging server | High |
The practical rule I use with clients: start with GTG on its own when you only need durable Google measurement. Add sGTM when you need to control what leaves the browser, enrich events with first-party data or feed non-Google platforms server-side. If you already run sGTM, moving script serving to the CDN takes load off the tagging server and costs less.
Who should use Google Tag Gateway (and who shouldn't)
GTG pays off most for advertisers whose bidding depends on Google conversion signals and whose audiences block or restrict third-party scripts. If that describes you, it is close to a no-brainer: no re-tagging, no server, and usually no extra cost.
Strong fit
- Google Ads and GMP advertisers on Smart Bidding, Performance Max or Demand Gen. Every recovered conversion feeds the bidding model. That is exactly where Google positions the feature (Google Ads announcement).
- Sites with a high share of Safari, Firefox, Brave or ad-blocker users. Tech, gaming, B2B SaaS and younger audiences tend to lose the most data to third-party script blocking.
- Brands already on Cloudflare, Akamai, Fastly, CloudFront or a Google Cloud load balancer. The edge layer you pay for already does the work.
- Teams without the budget or skills for sGTM. GTG with a CDN needs no tagging server; Brainlabs notes sGTM typically adds hosting cost while the Cloudflare route does not (Brainlabs).
- Teams already running sGTM. Moving script serving to the CDN reduces latency and server load (Google).
Weaker fit or extra work
- Sites on fully hosted platforms with no control of routing. If you cannot add a path rule at the edge, you cannot run the CDN route.
- Stacks driven mainly by non-Google tags. A first-party GTM container helps those tags load, but Meta, TikTok and similar vendors still call their own domains.
- Third-party tag managers like Tealium or Ensighten. Brainlabs notes these must use the
gtag.jsroute (Brainlabs). - Very low-traffic sites. The uplift is real but small in absolute terms, and you will struggle to measure it.
Google Tag Gateway results: real-world uplift data
A realistic expectation is roughly 9–18% more measured Google Ads conversions, with the gain concentrated in Safari, Firefox and ad-blocker traffic. Those conversions were already happening; GTG makes them visible to reporting and bidding.

GTG alone tends to add low-to-mid teens. The highest figure pairs it with Enhanced Conversions, and Google's 2025 number counts tag loads rather than conversions.
| Source | Setup | How it was measured | Other reported effects |
|---|---|---|---|
| Google Ads announcement (May 2025) | GTG, various | Google tag script loads, 7-day median, Apr 2025 | |
| Google internal data, cited by Akamai (Mar 2026) | GTG, various | Conversions, average across adopters | |
| DoYouSpain, online travel (TRKKN) | GTG via sGTM | Google Ads conversions, causal impact analysis | +11% paid Safari and Firefox sessions in GA |
| Home improvement retailer (Brainlabs) | GTG via Cloudflare one-click | Conversions | +27% with Consent Mode and Enhanced Conversions added |
| Insurance provider (Brainlabs) | GTG server-side + Enhanced Conversions | Conversions, causal impact analysis | −18.7% CPA |
| Adswerve client base (Adswerve) | GTG, various | Measured conversions |
How to measure your own uplift
- Baseline first. Export 4–8 weeks of Google Ads conversions and GA4 sessions, split by browser, before go-live.
- Change one thing at a time. Don't ship GTG in the same week as Enhanced Conversions or a CMP change, or you can't attribute the lift.
- Watch the browser split. The clearest signal is a jump in Safari and Firefox sessions relative to Chrome.
- Use a causal method for the headline number. Causal impact or a pre/post with a control series (for example, a market or property without GTG) beats a simple before/after.
- Cross-check with server or CDN logs. Compare page views in your logs with GA4 page views to see how much of the gap closed.
How to set up Google Tag Gateway: options at a glance
Pick the route that matches the edge layer you already run. Google offers two modes: in-UI setup, where GTM or the Google tag pushes the config to your provider (Cloudflare, Akamai, Fastly, Google Cloud), and self-service setup, where you build the routing rule yourself on any CDN or load balancer (setup guide).

Every route ends in the same first-party path; only who builds the rule changes. The table below has the details for each.
| Route | Mode | Where you configure it | On-page snippet change | Notes |
|---|---|---|---|---|
| Cloudflare | In-UI | GTM Admin › Google tag gateway, or Cloudflare dashboard | Not needed; Cloudflare overrides the existing script | Free on any plan; applies to the whole zone, including subdomains |
| Cloudflare Snippets | Self-service | Rules › Snippets | Yes | Snippets need a Pro plan or higher |
| Akamai | In-UI or self-service | Property Manager rule + Origin Server behavior | Yes for self-service | Enable Content Targeting (EdgeScape) for geo headers |
| Fastly | In-UI or self-service | Condition, Host and two VCL snippets | Yes for self-service | Add geo headers in both vcl_miss and vcl_pass |
| Google Cloud load balancer | In-UI or self-service | External Application LB: Internet NEG backend + routing rule | Yes for self-service | Geo comes from LB custom request headers |
| Amazon CloudFront | Self-service (Tag Assistant-guided) | New origin + behavior | Yes | Caching disabled; forward all viewer headers except Host |
| Any other CDN, LB or web server | Self-service | Origin {TAG-ID}.fps.goog + path rule | Yes | You must add the geo headers yourself |
| Server-side GTM | Self-service | Tagging server serves scripts (or pair with a CDN) | Yes | Highest control; adds hosting cost |
How to set up Google Tag Gateway on Cloudflare
On Cloudflare, GTG takes a few clicks and is free on any plan; requests through the gateway do not count towards other Cloudflare billing (Cloudflare docs).
Before you begin
0 of 41. Configure the gateway in GTM
- In your GTM container, go to Admin › Google tag gateway.
- Review the domain list. Statuses are First-party (active), Not started, Paused and Pending (enabled, no diagnostics yet).
- Confirm the measurement path, or change it to one that is not in use on your site.
- Click Sign into Cloudflare and grant Google permission.

2. Select your domains
- Click Manage domains.
- Tick the domains to enable. Domains are grouped as Tagged, Untagged (GTG will add the missing tag automatically) and Other active domains.
- Click Done inside the panel. Closing it without clicking Done discards your changes.
- Back on the main screen, the status should read Active.


Alternative: enable it from the Cloudflare dashboard
If you already know the tag ID, go to the Google Tag Gateway page in the Cloudflare dashboard, select the domain, switch on Turn on and configure Google Tag Gateway, enter the tag ID and path, and save (Cloudflare docs).
Rolling back
In the Google Tag Gateway screen, click Configure › Delete. This detaches Cloudflare from the container and disables GTG on all active domains at once (Google Help).
How to set up Google Tag Gateway on any CDN or load balancer
Self-service setup is three moves: reserve a path, route it to Google with geo headers, then point your page snippet at the path. All code below follows Google's setup guide; swap in your own domain, path and tag ID.
1. Reserve a measurement path
- The path must be unused on your domain, cannot be
/, and must be 100 characters or fewer. - One GTM container needs one path. Each extra container or standalone
G-/AW-tag needs its own path and origin. - The edge rule reroutes everything under the path, so a collision will break real pages.
| Use case | ID | Path | Origin endpoint |
|---|---|---|---|
| GTM container | GTM-ABCDEF | /metrics/ | gtm-abcdef.fps.goog |
| Standalone Google tag | G-12345 | /g12345/ | g-12345.fps.goog |
2. Route the path to Google
Cloudflare Snippets (Pro plan and above). Create a snippet named with the tag ID (lowercase, underscores only), then add a rule with the expression (starts_with(http.request.uri.path, "/metrics/")).
export default {
async fetch(request) {
const newRequest = new Request(request);
const url = new URL(request.url);
url.hostname = 'fps.goog';
newRequest.headers.set('X-Gtg-Implementation', 'Snippet');
newRequest.headers.set('X-Gtg-Tag-Id', 'GTM-ABCDEF');
newRequest.headers.append('X-Forwarded-For', request.headers.get('CF-Connecting-IP'));
newRequest.headers.set('X-Forwarded-Country', request.cf.country);
newRequest.headers.set('X-Forwarded-Region', request.cf.regionCode);
newRequest.headers.set(
'X-Forwarded-Geolocation',
`latlong=${request.cf.latitude},${request.cf.longitude};` +
`city=${request.cf.city}`,
);
return await fetch(url, newRequest);
},
};Google Cloud External Application Load Balancer. Create a backend service (for example measurement-be-svc) with an Internet NEG pointing at gtm-abcdef.fps.goog over HTTPS, add these custom request headers, then add a routing rule for host *, path /metrics/* to that backend. Cloud CDN and Cloud Armor are not required on this backend.
| Header | Value |
|---|---|
Host | gtm-abcdef.fps.goog |
X-Forwarded-CountryRegion | {client_region_subdivision} |
X-Forwarded-Geolocation | latlong={client_city_lat_long};city={client_city} |
Akamai. In a new Property Manager version, add a rule matching Path /metrics/* with an Origin Server behavior: hostname gtm-abcdef.fps.goog, Forward Host Header set to Origin Hostname. Add Content Targeting (EdgeScape) for geolocation, test on staging, then activate. Don't strip response headers on this rule: a missing Content-Type breaks the scripts.
Amazon CloudFront. Add an origin gtm-abcdef.fps.goog (HTTPS only), then a behavior for /metrics/* with compression off, all HTTP methods allowed, cache policy CachingDisabled and origin request policy AllViewerExceptHostHeader. Move it above every other behavior in precedence.
Fastly. Create a Request condition req.url.path ~ "^/metrics", a Host fps.goog with Override host fps.goog attached to that condition, and the same VCL snippet in both vcl_miss and vcl_pass:
if (req.url.path ~ "^/metrics") {
set bereq.http.X-Gtg-Tag-Id = "GTM-ABCDEF";
set bereq.http.X-Forwarded-Country = client.geo.country_code;
set bereq.http.X-Forwarded-Region = client.geo.region;
set bereq.http.X-Forwarded-Geolocation = "latlong=" +
client.geo.latitude + "," + client.geo.longitude + ";city=" +
client.geo.city;
}Any other CDN, load balancer or reverse proxy. The recipe is always the same:
- Add an origin
gtm-abcdef.fps.googand overrideHostto match it. - Forward all cookies and query strings; disable caching on the path.
- Send geolocation as
X-Forwarded-CountryRegion(ISO 3166-2, for exampleGB-ENG) or asX-Forwarded-Country+X-Forwarded-Region. If both are present,X-Forwarded-CountryRegionwins. - Route
/metrics/*to the origin with higher priority than your default rule.
3. Point the page snippet at the path
For GTM, change only the script source. The rest of the snippet stays the same.
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
'/metrics/';f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-ABCDEF');</script>
})(window,document,'script','dataLayer','');</script>
<!-- End Google Tag Manager -->For a standalone Google tag:
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-12345"></script>
<script async src="/g12345/"></script>4. Run the health checks
Google exposes two endpoints on every gateway path. Both must return ok.
# Routing works
curl -s https://example.com/metrics/healthy
# ok
# Geolocation headers arrive
curl -s "https://example.com/metrics/?validate_geo=healthy"
# ok
# The container itself is served first-party (expect 200 and a JavaScript content type)
curl -sI "https://example.com/metrics/?id=GTM-ABCDEF" | grep -iE "^HTTP|content-type"Google Tag Gateway QA: how to prove it's working
A GTG launch passes QA when the container loads from your path, hits route through it, location and consent still behave, and nothing is double-counted. Run the checks below on staging first, then again in production.
1. Before go-live
2. Browser checks (DevTools › Network)

So when you test from an EEA connection, a GA4 request going straight to a Google domain is not a failed setup.
3. Tag Assistant and GTM
4. Location and consent
5. Platform-level validation (first 1–2 weeks)
Pitfalls, privacy and governance
Most GTG problems come from the edge configuration or from consent, not from Google. Plan for these before launch.
Privacy and consent
- Consent still rules. GTG does not circumvent privacy controls or override consent choices (TRKKN). Google advises adopting Consent Mode and reviewing consent settings before enabling it, because GTG affects tag firing behaviour (Google Help).
- Only Google cookies are processed. Non-Google first-party cookies forwarded through the gateway are dropped; Google does not process or store them (Google Help).
- Location depends on your headers. Google sees your CDN's IP, so missing or stripped geo headers produce wrong geo reports and can break region-specific Consent Mode defaults. Google also asks that the true client IP is forwarded unaltered, for example in
X-Forwarded-For(Google Help). - Update your disclosures. Your privacy notice and cookie policy should reflect that Google measurement now flows through your domain and CDN. Check your CDN data processing terms with legal.
Technical pitfalls
- Double-loading. Old snippet plus new path means two containers and inflated metrics. Remove the old source in the same release.
- Path collisions. The rule captures everything under the path. Never reuse a path your app or CMS serves.
- Caching and compression. Cache the gateway path and you will serve stale containers or mix up responses. Disable caching; on CloudFront, Google also asks you to turn off automatic compression.
- Security rules. WAF, bot management or header-rewrite rules can block or mangle gateway traffic. Exempt the path deliberately and document why.
- Zone-wide scope on Cloudflare. The in-UI integration applies to every subdomain in the zone, including staging hosts you may not want measured.
- Multiple containers. Every GTM container or standalone tag needs its own path. With sGTM in the mix, scripts and collection need two separate paths, neither containing
/gtm. - Content Security Policy. First-party serving usually simplifies CSP, but confirm
script-srcandconnect-srcallow'self'before removing Google domains. - Expectation setting. Some blockers still match on script fingerprints, and GTG does nothing for non-Google vendor endpoints. Promise a measurable uplift, not 100% coverage.
Governance
- Record the path, owner and rule ID in your tracking plan and CDN runbook, so a future CDN migration doesn't silently drop it.
- Treat the gateway rule as production measurement infrastructure: change control, staging tests and an uptime check on
/metrics/healthy.
Google Tag Gateway FAQ
Does GTG cost anything? Google does not charge for it. On Cloudflare it is free on any plan and gateway requests don't count towards other Cloudflare billing. On other CDNs and load balancers, normal request pricing applies.
Do I have to retag? No. Tags, triggers and variables stay as they are. The Cloudflare in-UI route needs no snippet change; self-service routes change only the script source.
Does GTG replace server-side GTM? No. GTG proxies Google requests; sGTM processes them. Google recommends using both for the most durable setup.
Will it beat every ad blocker? No. It mitigates browser restrictions and many blockers, but sophisticated blocking can still identify the traffic.
Why do EEA users still hit Google domains for GA4? By design. Google routes Google Analytics data for EEA users directly to regional endpoints; Google Ads conversion hits still use your path.
What about apps? GTG is for web tags. App measurement through the Firebase SDK is unaffected.
I've seen "first-party mode" in older docs. Is that the same thing? Yes, that was its earlier name. Some Google help links still point to URLs under /tag-manager/first-party/.
Wrapping up
GTG is the cheapest durable-measurement win available to most Google advertisers right now. It is one routing rule, no new server and no retagging, and it typically recovers a high single-digit to high-teens percentage of conversions that were happening but never reported.
Ship it in this order: get Consent Mode right, enable GTG, run the QA checklist, measure the uplift for two to four weeks, then layer Enhanced Conversions and, where you need control over the payload, server-side GTM.
Sources
- Google tag gateway for advertisers — Google for Developers
- Set up Google tag gateway for advertisers — setup guide
- Google tag gateway guide — choose a setup
- Google tag gateway with CDN + sGTM
- Load Google scripts first-party with server-side tagging
- Google Ads announcement, May 2, 2025
- Set up GTG in Google Tag Manager with Cloudflare — Google Help
- Google tag gateway cookie handling — Google Help
- How Google tag gateway sets location — Google Help
- Cloudflare docs: Google tag gateway for advertisers
- Cloudflare blog: First-party tags in seconds
- Akamai blog: Google tag gateway on Akamai
- Brainlabs: From blind spots to 11%+ conversions growth
- Adswerve: Strengthen your first-party data foundation with GTG
- TRKKN: Guide to Google Tag Gateway 2026
- DoYouSpain case study (Google / TRKKN)
I've spent almost a decade with measurement. I helped brands from all sizes, industries and locations, which gave me confidence enough to write posts that will bring value to you.
More articles →