Introduction
As third-party cookies phase out and browser privacy restrictions tighten, first-party tracking has become essential for maintaining accurate analytics and marketing attribution. Google Tag Manager Server-Side (sGTM) combined with GA4 provides a robust solution for first-party data collection that respects user privacy while maintaining data accuracy.
This guide walks through the complete architecture, setup, and implementation of a server-side tracking infrastructure — from DNS configuration to Facebook Conversions API integration.
Why Third-Party Cookies Are Dying
Safari — Intelligent Tracking Prevention (ITP)
Apple led the charge with ITP, progressively restricting tracking since 2017:
- ITP 2.0 (2018): Third-party tracking cookies blocked immediately
- ITP 2.1 (2019): JavaScript-set first-party cookies (like
_ga) capped to 7-day expiry - ITP 2.2 (2019): Further reduced to 1-day expiry when users arrive from classified tracker domains (Facebook ads, Google ads)
- Safari 14+ (2020): CNAME cloaking detection added
With ~18-20% global browser market share (over 30% on mobile in the US), Safari’s restrictions significantly impact analytics accuracy.
Firefox — Enhanced Tracking Protection (ETP)
Firefox introduced Total Cookie Protection (default since Firefox 103 in 2022), which confines every cookie to the site where it was created. A Facebook cookie on site-a.com cannot be read on site-b.com, effectively killing third-party cookie-based tracking.
Chrome — Privacy Sandbox
Google reversed its plan to fully deprecate third-party cookies in Chrome (announced July 2024), but the trend is unmistakable. Safari and Firefox already block them, ~30-40% of desktop users run ad blockers, and privacy regulations continue tightening. Server-side first-party tracking is the new baseline.
Server-Side vs. Client-Side Tagging
| Aspect | Client-Side | Server-Side |
|---|---|---|
| Where tags execute | User’s browser | Your server |
| Browser requests | One per vendor (many) | One (to your server) |
| Cookie mechanism | JavaScript document.cookie | HTTP Set-Cookie header |
| ITP impact | 7-day / 1-day cap | Full lifetime (HTTP-set, not capped) |
| Ad blocker resilience | Low | High (first-party subdomain) |
| Data control | Vendors collect freely | You control what leaves your server |
| Page performance | Multiple heavy scripts | One lightweight request |
| Cost | Free | Server infrastructure costs |
Architecture Overview
The data flow for server-side tagging:
[Browser] → loads GTM Web Container
|
| GA4 sends data to https://data.yourdomain.com/g/collect
| (instead of https://www.google-analytics.com/g/collect)
v
[Custom Subdomain: data.yourdomain.com]
| DNS CNAME → your sGTM server (Cloud Run)
v
[GTM Server-Side Container]
| GA4 Client parses request into event data
|
+--→ GA4 Tag → Google Analytics 4
+--→ Facebook CAPI Tag → Facebook Conversions API
+--→ Google Ads Tag → Google Ads
|
v
[Response with first-party Set-Cookie headers back to browser]
Step-by-Step Implementation
Step 1: Create a Server-Side GTM Container
- Go to tagmanager.google.com and log in
- Click “Create Container” (or Admin → “+”)
- Name it descriptively (e.g., “yourdomain.com - Server”)
- Select “Server” as the target platform
- Choose automatic provisioning via Google Cloud (recommended) or manual deployment
- Note your Container ID (
GTM-XXXXXX) and the Container Config string from Admin → Container Settings
Step 2: Deploy the Server Container on Google Cloud Run
# Ensure gcloud CLI is installed and authenticated
gcloud services enable run.googleapis.com
# Deploy the production server
gcloud run deploy sgtm \
--image gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--min-instances 1 \
--set-env-vars CONTAINER_CONFIG=<your_config_string>
# Deploy a separate preview server (for GTM debug mode)
gcloud run deploy sgtm-preview \
--image gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--min-instances 1 \
--set-env-vars CONTAINER_CONFIG=<your_config_string>,RUN_AS_PREVIEW_SERVER=true
Alternative hosting: You can also deploy on Google App Engine, AWS (ECS/Fargate), or managed providers like Stape.io (~$20/month) which handles deployment, scaling, and custom domain setup.
Step 3: Configure Custom Subdomain (DNS CNAME)
This is the critical step that makes everything first-party:
- Choose a subdomain like
data.yourdomain.comorcollect.yourdomain.com - Create a DNS CNAME record pointing to your Cloud Run URL (e.g.,
your-project-abc123.a.run.app) - Map the custom domain in Cloud Run: Cloud Run → “Manage Custom Domains” → add your subdomain. SSL is provisioned automatically via Let’s Encrypt.
- Verify: Navigate to
https://data.yourdomain.com/healthy— it should return “ok” - Update GTM: Set the Server Container URL to
https://data.yourdomain.comin Admin → Container Settings
Step 4: Configure the GA4 Client in sGTM
The GA4 Client receives and parses incoming requests:
- Open your Server-Side GTM container → “Clients”
- The GA4 Client is auto-created. Open its settings.
- Enable “Set first-party cookies” — this is the key setting. The client will set the
_gacookie via HTTPSet-Cookieheader from your domain, bypassing Safari ITP’s 7-day cap. - Enable the option to read existing JavaScript-set
_gacookies to preserve returning-user recognition during migration.
Step 5: Configure the GA4 Tag in sGTM
- Go to “Tags” → “New” → select “Google Analytics: GA4”
- Leave the event data source as default (auto-detected from GA4 Client)
- Set trigger to “All Events” (where Client Name equals “GA4”)
- Optionally: redact IP addresses or remove PII before sending to GA4
Step 6: Update Client-Side GTM to Route Through sGTM
In your Web (client-side) GTM container, find your GA4 Configuration Tag and set the server_container_url:
// Option 1: In GTM Web Container
// GA4 Config Tag → "Send to server container" → https://data.yourdomain.com
// Option 2: Using gtag.js directly
gtag('config', 'G-XXXXXXX', {
server_container_url: 'https://data.yourdomain.com'
});
// Option 3: First-party script serving (maximum ad-blocker resilience)
// Replace:
<script src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
// With:
<script src="https://data.yourdomain.com/gtag/js?id=G-XXXXXXX"></script>
First-Party Cookie Configuration
This is the core advantage of server-side tagging:
- JavaScript-set cookies: Safari ITP caps to 7 days (or 1 day from ad click). A user who visits every 8 days looks like a new user every time.
- HTTP-set cookies from your domain: Not capped by ITP. Can persist for full lifetime (up to 400 days per EU regulations). Studies show 20-40% improvement in returning user identification after implementing sGTM.
Verify in Chrome DevTools → Application → Cookies: the _ga cookie should show your domain (e.g., .yourdomain.com) with a proper long-term expiry.
Integrating Facebook Conversions API (CAPI)
Facebook CAPI sends events server-to-server, complementing or replacing the browser pixel:
Setup Steps
- Install the template: In sGTM, go to Tags → New → Community Template Gallery → search “Facebook Conversions API”
- Get credentials: In Facebook Events Manager → your Pixel → Settings → generate an access token
- Configure the tag:
- Enter your Pixel ID and Access Token
- Map GA4 events to Facebook events (
page_view→PageView,purchase→Purchase, etc.) - Set the
event_idfor deduplication with the browser pixel - Pass user data: hashed email, phone,
fbc/fbpcookies, IP, user agent
- Deduplication: Generate a unique event ID client-side, pass it to both the browser pixel and sGTM. Facebook deduplicates automatically using
event_id+event_name. - Test: Use Facebook’s Test Events tool with a
test_event_codeto verify events arrive correctly.
Benefits Summary
- Data accuracy: Longer cookie lifetimes mean better returning-user recognition. Recover 10-30% of events lost to ad blockers.
- Performance: Instead of loading 5-10 vendor scripts, one lightweight request goes to your server. Typical improvement: 50-100ms+ in Total Blocking Time.
- Privacy and data control: Inspect, modify, or redact data before it leaves your server. Strip IP addresses, remove PII from URLs, add server-side enrichment.
- Security: No third-party scripts running in the browser eliminates supply-chain attack risk.
Cost Considerations
| Monthly Pageviews | Estimated Cost |
|---|---|
| Up to 100,000 | $0 - $5 (mostly free tier) |
| 100K - 500K | $5 - $25 |
| 500K - 1M | $25 - $50 |
| 1M - 5M | $50 - $150 |
| 5M - 10M | $100 - $300 |
Note: --min-instances 1 adds ~$10-15/month but eliminates cold starts. Managed providers like Stape.io start at ~$20/month.
Testing and Debugging
GTM Server-Side Preview Mode
Click “Preview” in the sGTM UI to see all incoming requests in real time. For each request, inspect:
- Which client claimed it (e.g., GA4 Client)
- Parsed event data (event name, parameters, user properties)
- Which tags fired and their outgoing HTTP payloads
- Response headers sent back (including
Set-Cookie)
GA4 DebugView
In GA4 → Admin → DebugView, server-sent events appear when debug_mode: true is set in the client-side config.
Common Issues
- No events in sGTM Preview: Verify
server_container_urlis correct andhttps://data.yourdomain.com/healthyreturns “ok” - Cookies not being set: Check response headers in sGTM Preview. Ensure the GA4 Client has “Set first-party cookies” enabled.
- Wrong geolocation: Ensure the
X-Forwarded-Forheader is forwarded to GA4
GDPR/CCPA Compliance
Server-side tagging does not replace the need for consent. Key considerations:
- You still need a Consent Management Platform (CMP) to collect consent before firing any tracking tags
- Google’s Consent Mode v2 (required for EEA advertisers since March 2024) is supported in sGTM. When consent is denied, GA4 sends cookieless pings and uses behavioral modeling.
- Deploy your Cloud Run instance in an EU region (e.g.,
europe-west1) for EU data residency - sGTM makes data minimization easier — strip IPs, remove PII, and control exactly what reaches each vendor
- Update your privacy policy to disclose server-side data collection
- Do not use sGTM to circumvent user choices. If a user opted out, respect it. Ethics and legal compliance come first.
Migration Strategy
We recommend a phased approach:
- Phase 1: Deploy sGTM alongside existing client-side tags. Both run simultaneously. Compare data for a few weeks.
- Phase 2: Move GA4 to server-side only. Remove the direct GA4 connection from client-side.
- Phase 3: Add Facebook CAPI and other vendor integrations to sGTM.
- Phase 4: Gradually remove client-side vendor scripts as server-side equivalents prove reliable.
Conclusion
Server-side tagging with GTM and GA4 is no longer optional — it is the foundation of modern analytics infrastructure. By routing data through your own first-party subdomain, you gain resilience against browser restrictions, improved data accuracy, better page performance, and stronger privacy controls.
The initial setup requires some infrastructure work, but the long-term benefits in data quality and compliance readiness far outweigh the modest hosting costs. Start with GA4, validate your data, then expand to Facebook CAPI and other platforms for a complete server-side analytics stack.