Last month I migrated XreplyAI from hardcoded gtag snippets to Google Tag Manager.
One container. All pixels managed in one place. No code deploys to add or change tags. I thought that was the hard part of getting ad attribution right.
It wasn't.
This morning I finished wiring Google Ads conversion tracking — trial_start firing server-side via the GA4 Measurement Protocol, conversion imported into Google Ads, bidding optimized for trials.
Then a new user signed up. And I had no idea where they came from.
Not because GA4 didn't know. GA4 knew — "google / cpc." But our users table has no UTM columns. So I can't:
- Calculate LTV by acquisition channel
- Know whether Google Ads or X Ads drove a signup
- Filter subscribers by source when making budget decisions
The fix is obvious in hindsight: store utm_source, utm_medium, utm_campaign, utm_content, and gclid on the user record at signup. Capture them from the URL on landing, pass them to the backend at magic link / signup time, persist once, never overwrite on subsequent logins.
It's a 2-hour task. I opened a GitHub issue this morning.
The lesson: GTM solves "where do my tags live." UTM columns on users solve "where did this specific person come from." You need both. Most founders running paid traffic have neither.
Fix it before you spend another dollar on ads.
Building XreplyAI in public — an AI social media tool for solo founders. BYOK model, voice-matched content across 8 platforms. xreplyai.com
Top comments (1)
UTM loss is one half; even with UTMs intact, channel comparisons drift if you only count conversions. Adding revenue per session as a second axis catches when one channel converts more at lower AOV — the CVR-only blind spot most attribution articles miss.
Sorry if my English sounds weird!!