Back to the Blog
Essay

UA to GA4 Migration: The Operator's Guide (With GTM Event Tracking)

A UA to GA4 migration guide from an operator who's done more than he can count. Map your events, dual-tag via GTM, and don't break your attribution chain.

By Sean Gowing
Jun 6, 20239 min read

UA to GA4 Migration: The Operator's Guide to Not Breaking Your Attribution

A UA to GA4 migration is, at its core, an exercise in mapping. You're taking every event you tracked in Universal Analytics, finding its match in Google Analytics 4's event-and-parameter model, and rebuilding the wiring — usually through Google Tag Manager — so the data lands clean on the other side. Do the mapping right and GA4 quietly starts telling you the truth. Get one value wrong and the whole attribution chain snaps without so much as a warning light.

I've done more of these than I want to count. Some were tidy. One — a large South African ecommerce brand mid-migration — was a genuine train wreck, and I'll get to that, because it's the most useful thing in this guide.

Universal Analytics is already in the rearview. The how-to underneath, though, hasn't changed: understand the new data model, map your events, dual-tag through GTM while you can, and validate like your pipeline depends on it. Because it does.

Table of Contents

<h2 id="ua-and-ga4">UA and GA4 collect data in two different languages</h2>

Here's the thing that trips people up. People hear "migration" and picture a copy-paste job — swap the tracking snippet, done. It's not that. UA and GA4 don't just look different. They think about your data differently.

In Universal Analytics, the basic unit was a hit. Pageviews, events, transactions — each a distinct hit type. An event hit carried a Category, an Action, and a Label, stacked in a rigid little hierarchy:

  • Event Category: video playing
  • Event Action: progress
  • Event Label: 50%

In GA4, that whole structure collapses into one idea: everything is an event. A pageview is an event. A purchase is an event. That video milestone becomes an event with parameters hanging off it:

  • Event: video_progress
  • Parameter: video_title
  • Parameter: video_percent

So the migration isn't translation, it's reconstruction. You're not converting Spanish to French. You're describing the same scene in a language with different grammar. That reframe is the difference between a clean cutover and three weeks combing through broken calls.

<h2 id="why-it-matters">Why the model change actually matters</h2>

The event-based model is genuinely better. Cross-device and cross-platform user journeys actually hang together. Engagement is measured in a way that resembles how people use sites in 2026, not 2013. And you stop bending every interaction into a Category/Action/Label shape that never quite fit.

But "better" and "automatic" are different words. GA4 gives you a more honest picture if you feed it honest data. That's the catch nobody puts in the headline. The platform won't fix sloppy mapping. It'll just report your sloppiness faster, and with a nicer interface.

This is the same lesson that shows up everywhere in tracking work: a number you believe beats a fast number you don't. "Real-time" is a vanity metric. Trustworthy is the goal. A GA4 dashboard refreshing every two seconds with garbage in it is worse than no dashboard, because now someone's making a budget decision off it.

<h2 id="train-wreck">The South African train wreck (and the lesson in it)</h2>

A large South African ecommerce brand came to us mid-migration. They'd done the surface-level stuff — new property, snippet on the site, GA4 "live." And on paper it was working. In reality it was a train wreck.

Events were firing, but the parameters were a mess. Values mapped to the wrong fields. Conversions that should've been clean were landing in the wrong buckets or not landing at all. Their event property coverage was sitting somewhere south of useless. The dashboard looked alive; the data was lying.

We spent weeks on it. Combing through every call, every trigger, every variable. Fixing broken mappings one at a time, re-firing, checking, re-firing. Tedious, unglamorous, exactly the work nobody wants to quote for. By the end we'd improved their data by an order of magnitude — a 70% improvement in GA4 data quality, with event properties actually coming through where they belonged.

Here's the lesson, and it's the whole post: mapping, mapping, mapping. When you build tracking systems, the mapping of data has to be correct. One wrong value and your entire attribution chain breaks. Not bends. Breaks. And the cruel part is it breaks silently — no error, no red banner. Just a slow drift of decisions made on numbers that were never real.

If your RevOps person is staring at a GA4 report that doesn't match the CRM, the stack is broken, not the person. That gap is almost always a mapping problem hiding in plain sight.

<h2 id="how-to-migrate">How to migrate UA to GA4, step by step</h2>

Here's the sequence I actually run. No fluff, no "familiarize yourself with the interface" filler.

1. Inventory what you're tracking now. Before you touch GA4, write down every event, goal, and conversion in your old UA setup. The button clicks, the form submits, the video plays, the ecommerce steps. You can't map what you haven't catalogued. Skip this and you'll discover the gaps in production, which is the worst place to discover anything.

2. Spin up the GA4 property and data stream. Create the new property, add a web data stream, turn on Enhanced Measurement for the freebies (scrolls, outbound clicks, site search). This is the easy 20%. Don't mistake it for done.

3. Map every event to the GA4 model. This is the 80%. Take each UA Category/Action/Label and decide what it becomes — an event name plus its parameters. Sweat the naming and the values. purchase is not Purchase is not purchase_complete. GA4 will treat those as three different things and never tell you.

4. Rebuild the tags — ideally in GTM. Recreate your tracking through Google Tag Manager so it's all in one place and you can dual-tag while UA history still matters to you. More on the GTM mechanics below.

5. Validate before you trust anything. Fire every event by hand, watch it land, confirm the parameters arrived intact. Then watch it for a few days against a source you already trust.

If you're on Webflow, the GTM container plumbing has its own gotchas — our Google Tag Manager + Webflow setup guide covers where things tend to go sideways.

<h2 id="gtm-event-tracking">GA4 event tracking via GTM: the part everyone botches</h2>

Google Tag Manager is where the real migration happens, and where most of the damage gets done. The good news: in most cases you can reuse the same triggers and variables from your UA configuration to fire your new GA4 events. You're not rebuilding from zero. You're re-pointing.

The workhorse move is dual-tagging — firing both UA and GA4 off the same trigger so you build GA4 history without going dark on your old reports. UA itself is gone now, but the dual-tag pattern is still how you run any parallel-tracking cutover, GA4 alongside a server-side container, say, or GA4 alongside an ad platform's own pixel.

When you map a UA event into GA4, GA4 gives you four flavors of event, and you check them in this order:

  1. Enhanced Measurement — does GA4 already capture this for free? (Outbound clicks, scrolls, file downloads, video engagement.) If yes, you're done. Don't rebuild what Google already gives you.
  2. Automatically-collected — events GA4 logs on its own (first_visit, session_start). Nothing to do.
  3. Recommended — Google's named events for common actions, especially ecommerce (purchase, add_to_cart, begin_checkout). Use these names exactly. This is where naming discipline pays off, because matching Google's spec unlocks reporting you'd otherwise build by hand.
  4. Custom events — only when none of the above fit. Your last resort, not your first move.

Walk down that list for every event. The instinct is to make everything custom because it's faster to think about. Resist it. A pile of custom events that duplicate Recommended ones is how you end up with a GA4 property that technically works and practically lies.

And if you're hand-coding with gtag.js instead of GTM — trickier, more places for a typo to quietly poison a parameter. Doable, but GTM exists for a reason.

One more, because I watch people do it constantly: don't tag your own internal links with UTMs. It corrupts attribution and off-spec mediums vanish into the (Other) bucket, never to return. Tag inbound only. If UTMs are part of your setup, the UTM formats guide goes deep on keeping them consistent.

<h2 id="validate">Validate it, or you're just guessing</h2>

Implementation without validation is a guess wearing a lab coat. Once the tags are firing, you verify — not "it looks live," but actually confirm the data is true.

Open GA4 DebugView and GTM Preview. Then go do the things a user does: click the buttons, submit the forms, run a test purchase, scroll the page. Watch each event arrive. Open it up and confirm the parameters came through with the right values, not just that an event fired. A purchase event with a blank value parameter is the kind of thing that looks fine in a list and is catastrophic in a revenue report.

Then let it soak. Run it a few days against something you already trust — your CRM, your payment processor, last month's UA baseline if you kept it. When GA4 agrees with reality, you're done. When it doesn't, you've got a mapping bug, and now you know where to dig. For the conversion-event specifics, our conversion tracking setup guide walks the GA4 side in detail.

This is the unglamorous part, and it's the part that separates a migration that works from one that merely launched. We've burned the weeks on a brand's broken event calls so we know exactly where the bodies are. If you'd rather not — that's what our tracking and analytics team does: we wire the signal path from click to closed-won and make sure the number you're staring at is one you can actually bet a budget on.

<h2 id="faq">FAQ</h2>

Is UA to GA4 migration still necessary?

Yes. Universal Analytics has stopped processing new data, so GA4 is the only live option in the Google Analytics stack. If you haven't migrated, you're flying blind on anything that happened after the cutoff — there's no "wait it out" left.

What's the hardest part of a UA to GA4 migration?

Event mapping. Translating UA's Category/Action/Label structure into GA4's event-and-parameter model is where accuracy makes or breaks the whole thing. One wrong value and your attribution chain breaks silently — no error message, just bad data you trust until you don't.

Do I have to use Google Tag Manager to migrate?

No, but it's the sane choice. GTM keeps every tag in one place, lets you reuse existing triggers and variables, and makes parallel-tracking far easier to manage. You can hand-code with gtag.js, but that's more surface area for a typo to quietly corrupt a parameter.

What are the four types of GA4 events?

Enhanced Measurement, Automatically-collected, Recommended, and Custom. When mapping a UA event, check them in that order — only build a Custom event when none of the first three fit. Reusing Recommended event names exactly unlocks built-in reporting.

Will I lose my historical UA data?

Your old UA data isn't carried into GA4 — the platforms store data separately and the models don't line up. Export anything you need to keep before access closes, and treat GA4 as a fresh baseline going forward. This is exactly why early dual-tagging mattered: it built GA4 history in parallel.

How do I know my GA4 migration actually worked?

Validate, then soak. Use DebugView and GTM Preview to confirm each event fires with the right parameter values, then run GA4 for a few days against a source you trust — your CRM or payment processor. When the numbers agree with reality, you're done. When they don't, you've got a mapping bug to chase.

Want this for your team?

Send us a brief and we'll come back with a fixed-price plan in 48 hours.