Approach 3 of 3

Server-Side GTM (sGTM)

Dedicated Cloud Run container on GCP — the enterprise standard for total data ownership

🏗️ GCP Infrastructure Stack

⚡ How the Data Flow Works

1
Browser loads GTM from your Cloud Run endpoint

The snippet below points to metrics.data-gateway.site/gtm.js. DNS resolves this to your GCP Global Load Balancer — no Google domain is ever visible.

2
Load Balancer routes to Cloud Run sGTM container

The Load Balancer forwards the request to your Cloud Run service. Cloud Run scales from 0 to N instances automatically based on traffic.

3
sGTM processes the hit server-to-server

The sGTM container receives the raw measurement hit. Before forwarding it, the server-side tags can enrich the payload — adding server-side user data, stripping PII, or transforming the event schema.

4
sGTM forwards to one or many vendors — server to server

GA4, Meta Conversions API, TikTok Events API, and others all receive the hit via secure server-to-server calls. No browser involved, no cookies required for the forwarding step — this is why server-side cookies last for years, not the 7-day ITP limit that Safari enforces on browser-set cookies.

5
Every hit is logged to Cloud Logging / BigQuery

Because the data passes through infrastructure you own, you can log every raw hit before it leaves your GCP project. This is essential for GDPR compliance, data audits, and ML model training.

💻 The GTM Snippet — Same Subdomain as Approach 2, Different Backend

The HTML snippet looks identical to Approach 2 — both point to metrics.data-gateway.site. The difference is what sits behind that domain: a Cloudflare reverse proxy (Approach 2) vs. a full GCP Cloud Run sGTM container (Approach 3).

<!-- sGTM snippet — points to Cloud Run via Load Balancer -->
<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://metrics.data-gateway.site/gtm.js?id='+i+dl;
  f.parentNode.insertBefore(j,f);
  })(window,document,'script','dataLayer','GTM-KSWQ3CCC');</script>

/* Infrastructure behind metrics.data-gateway.site
   (Approach 2): Cloudflare Worker → googletagmanager.com (proxy)
   (Approach 3): GCP Load Balancer → Cloud Run sGTM container → Google/Meta/etc.

   The browser can't tell the difference.
   But Approach 3 gives you a full server log of every hit. */

🧪 Live Demo — Fire Events

Events travel from the browser → metrics.data-gateway.site → Cloud Run sGTM container → GA4 (and any other connected vendors).