The Problem: A SaaS Platform Flying Blind
A B2B SaaS company in Canada — project management software for construction firms — was running Google Ads and LinkedIn Ads campaigns targeting construction managers and project owners.
Their target audience skews towards technical users. And technical users use ad blockers.
A technical audit revealed:
- 28% of their website visitors ran ad blockers (vs. ~10% industry average)
- Another 18% used Safari with ITP enabled, which was clearing the Google Ads click ID (
gclid) within 24 hours - The browser-side GTM container was loading 17 third-party scripts, contributing 420ms of page load delay
Total estimated conversion data loss: 34% of real conversions going unattributed.
The Smart Bidding algorithms were training on 66% of their actual conversion data. The campaigns weren't underperforming — they were being optimised on an incomplete picture.
Why Ad Blockers Break Browser-side GTM
Most people think of ad blockers as just hiding ads. But modern ad blockers (uBlock Origin, Brave's built-in blocker, AdGuard) also block tracking scripts — including the Google Tag Manager container, Google Ads conversion tag, GA4, and LinkedIn Insight Tag.
When a user with an ad blocker visits your website and converts, none of your tracking fires. The conversion is real. The tracking is dead.
Browser-side GTM has no workaround for this. The scripts load from Google's CDN (googletagmanager.com) — which is on every major ad blocker's block list.
Server-side GTM solves this by loading a first-party script from your own domain (e.g., tag.yourcompany.com). Ad blockers cannot block your own domain without breaking your website. The tracking script loads, the conversion fires, and the data reaches your ad platforms.
The Migration Process
Phase 1: Cloud Run Infrastructure (Days 1–3)
We provisioned a server-side GTM container on Google Cloud Run (GCP):
- Region:
northamerica-northeast1(Toronto) for latency proximity to the Canadian user base - Minimum instances: 2 (to eliminate cold start delay)
- Custom domain:
tag.theircompany.comwith automatic SSL via GCP Certificate Manager - Auto-scaling configured for traffic spikes
Monthly hosting cost: approximately CAD$18/month at their traffic volume.
Phase 2: First-party Proxy Configuration (Days 4–6)
Updated their website to load GTM via the first-party proxy:
- Changed GTM snippet URL from
https://www.googletagmanager.com/gtm.jstohttps://tag.theircompany.com/gtm.js - This single change meant ad blockers could no longer block the GTM container
Phase 3: Server Clients Setup (Days 7–12)
Configured server-side clients in the sGTM container:
- GA4 client: Routes all GA4 events through server (no
analytics.google.comrequest from browser) - Google Ads Conversion Linker: Extended
gclidlifetime from 24 hours (Safari ITP limit) to 400 days (first-party server cookie) - LinkedIn Insight Tag client: Server-to-server LinkedIn conversion tracking
Phase 4: Browser-side GTM Cleanup (Days 13–16)
With server-side handling the core tracking, we stripped unnecessary scripts from the browser-side container:
- Removed: GA4 browser tag (now server-side)
- Removed: Google Ads conversion tag (now server-side)
- Removed: LinkedIn Insight Tag (now server-side)
- Removed: 4 dead tags from previous vendor integrations
Remaining in browser container: 3 lightweight tags (Hotjar, Intercom, A/B test framework).
Phase 5: Parallel QA (Days 17–21)
Ran both browser-side and server-side configurations simultaneously for 7 days:
- Compared GA4 session counts between old and new
- Verified Google Ads conversion numbers in both environments
- Confirmed no data duplication (event deduplication active)
Results
| Metric | Before | After | Change |
|---|---|---|---|
| Attributed Conversions (monthly) | 156 | 209 | +34% |
| Page Load Time (LCP) | 3.8s | 3.38s | -420ms |
| Data Loss from Ad Blockers | 28% | ~0% | Eliminated |
| Safari ITP gclid Loss | ~18% | ~0% | Eliminated |
| Data Accuracy | ~66% | 97% | +31pts |
| Monthly Hosting Cost | $0 | CAD$18 | – |
The 420ms LCP improvement moved them from the "Needs Improvement" to "Good" range in Core Web Vitals — which directly impacts Google Ads Quality Score and landing page experience rating.
The 34% conversion recovery retrained Target CPA bidding within 5 weeks, with CPA dropping 22% as Smart Bidding found better signals.
Technical Notes
Cold starts: Google Cloud Run has a cold start latency (~200–800ms) on the first request after idle periods. We set minimum instances to 2 to eliminate cold starts entirely.
gclid preservation: Safari's ITP limits client-side cookie duration to 24 hours. By setting the gclid as a server-side HttpOnly cookie through the sGTM server, the 400-day conversion window is preserved.
Ad blocker detection: We verified ad blocker rates before and after using a server-side JavaScript snippet that loads before the GTM proxy — confirming that the first-party domain successfully bypassed blockers.

