Server-side GTM moves tag execution from the user’s browser to a server you control. The pitch: better performance (fewer client-side scripts), better data accuracy (no ad blockers), better privacy (data stays on your server before forwarding). The reality: every migration we have observed breaks at least three things that nobody anticipated.
Server-side GTM is not a drop-in replacement. It is a fundamentally different architecture. Client-side GTM reads the DOM, the data layer, cookies, and the URL. Server-side GTM receives an HTTP request with whatever data the client chose to send. Everything the server-side container does not explicitly receive, it does not have.
GA4’s client ID (_ga cookie) is set by the client-side gtag.js library. When you move GA4 to server-side, the client sends a measurement protocol hit to your server-side endpoint. If the client-side snippet is misconfigured or removed too aggressively, the _ga cookie stops being set. New sessions generate new client IDs. Your user counts inflate. Your returning visitor metrics collapse. Your attribution windows reset.
The fix is to keep a minimal client-side GA4 snippet that manages the cookie and sends hits to your server-side endpoint via a first-party domain. But many migration guides tell you to remove all client-side scripts. Do not do that until you have verified cookie management is handled.
When you run both the client-side Meta Pixel and server-side Conversions API, you must deduplicate events. Both channels send the same conversion to Meta. Without deduplication, Meta counts it twice. Your conversion count doubles overnight. Your CPA appears to drop 50%. Meta’s bidding algorithm optimises against inflated conversions.
Deduplication requires sending the same event_id from both client and server. If the client-side pixel generates a random event ID and the server-side CAPI call generates a different one, Meta cannot match them. You need a shared event ID, typically generated on the page and passed to both channels.
Your CMP runs in the browser. It sets consent state via JavaScript. When the browser sends a hit to your server-side GTM endpoint, the consent state is not included in the HTTP request unless you explicitly add it. The server-side container has no idea whether the user consented. It processes all hits equally. Your server-side tags fire for users who denied consent.
Client-side GTM reads document.referrer and URL parameters directly. Server-side GTM receives whatever the client sends. If your client-side snippet does not explicitly forward the referrer header and UTM parameters to the server-side endpoint, that data is lost. Your source/medium attribution breaks. All server-side traffic appears as direct/none.
The server-side endpoint still requires a client-side snippet to send data. That snippet loads JavaScript, reads the DOM, and makes HTTP requests. If you keep client-side fallback tags running alongside server-side (which most implementations do during migration), you are running more scripts than before. Page speed gets worse, not better.
Server-side GTM runs on Google Cloud. If your server-side container is deployed in us-central1 and your users are in India, every hit travels to the US and back. That is 200–400ms of latency per hit. For a page that sends 8 hits on load, that is up to 3.2 seconds of network time. Deploy the container in the region closest to your users.
Client-side GTM custom JavaScript variables have access to window, document, dataLayer, and the full DOM. Server-side GTM custom JavaScript variables have access to the event data object — nothing else. Any variable that reads from the DOM, checks the URL, or accesses cookies must be rewritten to read from the incoming event data instead.
Not all tags have server-side equivalents. Meta has CAPI. Google Ads has enhanced conversions. But Hotjar, Intercom, TikTok, LinkedIn, Criteo, and dozens of other vendors do not have server-side tag templates in GTM. These tags must remain client-side. Your “server-side migration” becomes a hybrid architecture where some tags run server-side and others remain in the browser.
Before migrating any tag to server-side:
Monitor all tag health metrics for 14 days after migration. Compare conversion counts, user counts, session counts, and revenue against pre-migration baselines. Any deviation above 5% indicates a migration issue.
Across every tag, every page, 24/7. Set it up in 5 minutes. No GTM dependency. No developer required.
Start 14-day free trial →Across every tag, every page, 24/7. Set it up in 5 minutes.
No GTM dependency. No developer required.