Server-side GTM setup checklist

last verified · against server-side GTM as of 2026-07

Production checklist for server-side Google Tag Manager: Cloud Run sizing, preview server env vars, first-party domain DNS, clients, and health checks.

What this is

An ordered checklist for taking a server-side Google Tag Manager (sGTM) container from nothing to a production deployment: hosting choice, sizing, preview server, first-party domain, data routing, clients, and verification. Every step reflects Google’s current official documentation; the few details the docs do not state are flagged inline instead of guessed.

Deployment options

Option Status Notes
Cloud Run Recommended (Google’s current default) Automatic provisioning from the GTM UI or manual
App Engine Still supported, no longer recommended Setup guide now points to Cloud Run
Manual / Docker Supported on “any environment that supports Docker” Single server or cluster

Docker image for Cloud Run and manual deployments: gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable — redeploying the stable tag picks up server updates.

Step 1 — Create the server container

  • GTM account menu → Create Container → name it → select type Server.
  • Choose Automatically provision tagging server (requires a Google Cloud billing account) or set it up manually.
  • Automatic provisioning deploys a testing configuration: one tagging server plus one preview server in us-central1. Google’s docs are explicit that it “should only be used for testing” — upgrade before production traffic.
  • Grab the Container Config string: server container workspace → container ID (top right) → Manually provision tagging server → Container Config. Every server instance needs it.

Step 2 — Size for production

Platform Minimum for production Autoscaling guidance Documented cost
Cloud Run 2 instances (“to reduce the risk of data loss”) 2–10 instances handle 35–350 requests/second ~$45/month per server (1 vCPU, 0.5 GB, CPU always allocated)
App Engine 3 servers 3–6 handle 50–200 requests/second ~$40/month per server

The often-repeated “at least 3 instances” advice is App Engine guidance; for Cloud Run the documented minimum is 2.

Step 3 — Configure the preview server

Run exactly one preview server instance — the docs say not to configure autoscaling beyond 1.

Environment variable Preview server Tagging server(s)
CONTAINER_CONFIG Required Required (same value on every instance)
RUN_AS_PREVIEW_SERVER true Not set
PREVIEW_SERVER_URL Not set Required — HTTPS URL of the preview server
PORT Optional Optional
GOOGLE_APPLICATION_CREDENTIALS, GOOGLE_CLOUD_PROJECT Optional Optional

Step 4 — Serve from your own domain

Google’s requirement: “your tagging server and your website have to run on the same domain” to get first-party benefits such as more durable cookies. (The community shorthand “same eTLD+1” does not appear in the official text.)

Option First-party cookies Setup
Same origin, e.g. https://www.example.com/metrics Best practice CDN/load balancer path rule /metrics/*: add the tagging server as a backend, override the Host header, forward cookies and query strings; avoid “gtm” in the path
Subdomain, e.g. metrics.example.com Yes Cloud Run domain mapping: verify ownership (Webmaster Central), create the A and AAAA records — “If there is a CNAME record shown in addition to the A and AAAA records, do not map the CNAME record”; managed SSL can take up to an hour
Default *.run.app “None. Can only set Javascript cookies.” No DNS work, but no HttpOnly cookies

After mapping: GTM Admin → Container Settings → remove the old URLs → Add URL.

Step 5 — Route data to the container

The mechanism is the server_container_url configuration parameter on the Google tag.

  • gtag.js sites:
gtag-config.js
gtag('config', 'TAG_ID', {
server_container_url: 'https://metrics.example.com',
});
  • GTM web container: create a “Google tag: Configuration settings” variable, add parameter server_container_url with the server URL, and attach it to the Google tag’s Configuration settings.
  • The container’s URLs live under Admin → Container Settings → Server container URLs. Current docs configure this via the parameter; no field literally labeled “Send to a server container” appears in them.

Step 6 — Configure clients

  • Server containers ship with two clients included: Google Analytics 4 and Measurement Protocol.
  • The GA4 client claims requests on path signatures like /collect, /g/collect, and /j/collect.
  • First-party script serving uses the “Google Tag Manager: Web Container” client to serve gtm.js/gtag scripts from your domain. Settings: allowed container ID, tag serving path (auto-generated random path; customizable, must start with /), and HTTP compression.
  • Since 2025-06-30, the GA client no longer supports dependency serving — serve all scripts through the web container client. This documentation area is now branded “Google tag gateway for advertisers”.
  • Cookies: in the GA4 client’s “Cookies and Client Identification”, keep JavaScript Managed until your custom domain is live — per the docs it is “the only method that will work until you change the domain settings”. Once the serving domain matches the site, server-managed cookies work: the server can “read and write cookies that are not visible to scripts in the page (HttpOnly cookies)”. The cookie name “FPID” circulating in the community is not in the official docs — the official term is server-managed cookies.

Step 7 — Verify

  • Health check — the endpoint is /healthy (anything citing /healthz is outdated):
health-check.sh
curl -i https://metrics.example.com/healthy
# expect HTTP 200 with body: ok
  • Server container Preview: open Preview, then load a page running the modified web tag in the same browser. Left panel lists incoming HTTP requests with their events; right panel tabs are Request, Tags, Variables, Event Data, and Console. Success looks like your GA4 hit under “Outgoing HTTP Requests from Server”.
  • First-party serving check: DevTools Sources tab — if www.googletagmanager.com still appears, first-party serving is not working.

Gotchas

  1. Cookies keep resetting even though sGTM is live. Cause: serving from the default *.run.app domain, which “can only set Javascript cookies”. Fix: map a custom domain on the same domain as the site (Step 4).
  2. Preview mode shows no requests. Cause: PREVIEW_SERVER_URL missing on tagging instances, or the preview service autoscaled past one instance. Fix: set the env var on every tagging server and pin the preview server to exactly 1 instance.
  3. Intermittent data loss in production. Cause: still running the auto-provisioned testing setup (a single tagging server). Fix: minimum 2 Cloud Run instances with autoscaling (2–10 covers 35–350 req/s).
  4. Domain mapping stuck or certificate errors. Cause: the CNAME record was mapped alongside the A/AAAA records, or the managed certificate is still provisioning. Fix: map only the A and AAAA records and allow up to an hour for SSL.
  5. Scripts still load from www.googletagmanager.com. Cause: relying on GA-client dependency serving (removed 2025-06-30) or a misconfigured web container client. Fix: configure the “Google Tag Manager: Web Container” client with your tag serving path and verify in DevTools Sources.
  6. Load balancer health checks fail. Cause: probing /healthz. Fix: probe /healthy and expect ok. (Official docs give no load-balancer-specific health-check guidance beyond the endpoint itself.)

Quick recipes

Manual Docker deployment — preview server first, then tagging servers pointed at it:

docker-manual.sh
# preview server (exactly one)
docker run -d -p 8080:8080 \
-e CONTAINER_CONFIG='<your Container Config string>' \
-e RUN_AS_PREVIEW_SERVER=true \
gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable
# tagging server (run 2+ behind your load balancer)
docker run -d -p 8080:8080 \
-e CONTAINER_CONFIG='<your Container Config string>' \
-e PREVIEW_SERVER_URL='https://preview.example.com' \
gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable

App Engine setup (legacy path, still documented) from Cloud Shell:

app-engine-setup.sh
bash -c "$(curl -fsSL https://googletagmanager.com/static/serverjs/setup.sh)"

Route a GA4 web stream through the container (see Step 5 for the GTM-web-container variant):

gtag-config.js
gtag('config', 'G-XXXXXXX', {
server_container_url: 'https://metrics.example.com',
});

What changed in 2025–2026

Date Change
2025-03-04 Google tag uses service workers to send data to sGTM
2025-05-08 “First-party mode” renamed Google tag gateway for advertisers
2025-06-30 Serve all scripts with the web container client; GA client dependency serving removed
2026-01-05 / 2026-06-01 Google tag gateway via Google Cloud (global external Application Load Balancer): Beta, then GA
2026-01-29 / 2026-05-14 Gateway integrations for Akamai, then Fastly (Cloudflare since 2024-10)
2026-06-22 Improved server-to-server conversion measurement (joins server data with browser signals when a GCLID is present)
2026-07-09 Container behavior change for unsupported installation paths

Google also published a dedicated guide for private preview servers on Cloud Run.

Sources

Official pages these steps were read from (2026-07-18/19):

Details not stated in official docs are flagged inline: the “eTLD+1” phrasing, a “Send to a server container” UI label, the “FPID” cookie name, and load-balancer health-check guidance.

Changelog

  • — Initial version, verified against official Google documentation.

dataLayer

0 events · 0 sent

    • home /
      writing /writing
      guides /guides
      work /#work
      about /about
      colophon /colophon
      toggle analyst mode ctrl+.
      print session receipt /#receipt