How Do You Verify Analytics Still Works After a Site Migration? A Pre- and Post-Cutover QA Playbook
A site migration is one of the few projects where everything can look fine and be badly broken at the same time. The pages render. The navigation works. Someone clicks through the top ten URLs on launch night, declares it good, and everyone goes to bed. Three weeks later a report lands showing organic sessions down 40%, and nobody in the room can say whether the site lost traffic or lost the ability to see it.
Those are two very different problems with two very different fixes, and separating them after the fact is close to impossible. The data you would need to tell them apart is precisely the data that went missing.
There is a way out, and it is not more dashboards. The fix is to send a known quantity of controlled traffic through the new site — before the cutover and immediately after — so you have a baseline you fully own. If you push exactly 500 sessions along a defined path and GA4 reports 190, you do not have a traffic problem. You have a tag problem, and you know it within the hour instead of the next quarter.
Why do analytics failures during a migration go unnoticed?
Broken tracking is silent by design. A missing analytics snippet does not throw a 500. It does not show up in uptime monitoring, it does not fail a build, and it does not affect a single visitor’s experience. The page loads perfectly. The only symptom is an absence, and absences are invisible until someone compares them against an expectation.
The timing makes it worse. Migrations almost always coincide with a genuine dip in traffic — redirects take time to be recrawled, rankings wobble, some URLs really do lose visitors. So when the numbers fall, there is a ready-made explanation sitting right there, and it is the wrong one often enough to be dangerous. Teams spend six weeks writing content to “recover from the migration” while the real issue is a consent-mode default that was flipped during the theme rebuild.
The other reason is coverage. Manual QA touches the homepage, a category page, maybe one product page, on one browser, in one country, on one device. A modern site has dozens of distinct templates, and analytics is usually implemented per template. The template nobody spot-checked is exactly the one that ships without a tag.
What actually breaks when a site moves?
Almost none of these failures are exotic. They repeat across migrations because they are structural consequences of moving a site, not one-off mistakes.
| Failure mode | What you see in reports | Why it happens |
|---|---|---|
| Tag missing on a template | Whole page groups vanish; totals drop | Snippet added to the layout, not to every layout |
| Duplicate tag firing | Sessions inflate; bounce rate collapses | Old hard-coded tag plus new tag manager container |
| Referrer stripped by redirects | Organic and referral traffic reclassified as direct | Meta-refresh or JS redirects instead of 301s |
| UTM parameters dropped | Paid and email campaigns lose attribution | Redirect rules that do not preserve query strings |
| Events renamed or unfired | Conversions flatline while revenue is unchanged | New DOM, old selectors in the event triggers |
| Mobile template untagged | Desktop looks normal, mobile disappears | Separate templates or AMP-style variants |
| Cross-domain linker broken | Checkout starts a new session; conversions unattributed | Domain list not updated for the new hostname |
Notice how many of these are only visible from a segment. Mobile-only, referral-only, one page group. A top-line session count can look nearly identical while an entire acquisition channel has stopped being measurable — which is why “traffic looks about the same” is not a passing grade.
How do you test analytics on staging before cutover?
Staging is where migration QA should happen, and it is usually skipped for a practical reason: staging has no traffic. You cannot validate that your reports behave correctly when nothing is generating reports. Real-time debug views help with a single hand-tested visit, but they tell you nothing about how a hundred visits distributed across templates and devices will aggregate.
Generated traffic closes that gap. Point a browser simulation campaign at the staging base URL and let it discover and visit internal links the way a visitor would. Because the sessions come from a real Chromium browser that scrolls, dwells and clicks through to sub-pages, whatever your tag is going to do in production is what it does on staging — including any client-side event that depends on scroll depth or time on page.
Two practical notes. Send the staging traffic to a separate GA4 property or a dedicated debug stream so you never contaminate the production dataset you are about to compare against. And run the campaign with a mixed device rate — a 50/50 desktop-to-mobile split surfaces the untagged mobile template that a desktop-only pass would sail straight past.
Give it a full 24 hours if you can. Traffic distributed across a day exercises caching layers, CDN behaviour and any time-based logic in a way that a burst of fifty visits in five minutes never will.
What should you check in the first hour after cutover?
The hour after DNS propagates is the cheapest possible moment to catch a tracking failure. Work through this in order — each step depends on the one before it being true.
- Confirm the property is receiving anything at all. One live session in the real-time report rules out the total-outage case in under a minute.
- Start a controlled run against the production base URL with a known session count and a known maximum pageviews per session. Write the expected numbers down before you look at any report.
- Check template coverage. Every page group that appeared in your pre-migration reports should appear now. A group that has fallen to zero is an untagged template, not a ranking change — nothing loses 100% of its traffic in an hour.
- Verify the desktop/mobile split matches the split you configured. A ratio that skews hard to one device means the other device’s template is not reporting.
- Test referrer preservation by sending sessions with an explicit referrer source. If they land in your reports as direct, a redirect in the chain is stripping the referrer.
- Fire a campaign with full UTM parameters attached and confirm source, medium and campaign name arrive intact. This is the single check that protects your paid spend.
- Walk the conversion path end to end and confirm each event still fires with the name your reports expect. Renamed events are as damaging as missing ones and much harder to spot.
- Compare delivered sessions against reported sessions. Anything below roughly 90% recorded needs a cause before you move on.
Eight checks, and every one of them produces a yes-or-no answer against a number you chose in advance. That is what makes the exercise useful — you are not interpreting a trend, you are comparing two integers.
How do you separate a tracking failure from a real traffic drop?
This is the question that makes controlled traffic worth the effort, and the logic behind it is simple. Organic traffic is an unknown input producing an unknown output; you can only observe the result. Generated traffic is a known input producing an observable output, which means any discrepancy between them belongs to the measurement layer.
So when sessions are down after a migration, run a fixed campaign and read the result:
- Controlled sessions arrive at close to full volume. Your tracking is intact and the drop is real — look at redirects, rankings, index coverage and crawl budget.
- Controlled sessions arrive short or not at all. Your tracking is broken. The organic “drop” is partly or entirely a reporting artefact, and no amount of SEO work will move it.
- Controlled sessions arrive but land in the wrong dimensions. Volume is fine, attribution is not. Check referrer handling, UTM preservation and channel grouping rules.
Three outcomes, three different next actions, and you get to the right one in an afternoon rather than a quarter. If you want to isolate the analytics layer specifically — separating a GA4 configuration problem from a site-delivery problem — a GA4 traffic campaign that fires measurement-protocol events directly bypasses the site entirely. If those events land correctly but browser-driven sessions do not, the fault is in the page, not the property.
What settings make a good migration QA run?
A migration test is not a traffic campaign and should not be configured like one. You want breadth of coverage and readable arithmetic, not volume.
| Setting | Suggested value | Reasoning |
|---|---|---|
| Sessions per day | 200–500 | Large enough to be unambiguous in reports, small enough to stay cheap |
| Max pageviews per session | 3–5 | Forces the crawler past the homepage into real templates |
| Bounce rate | 20–30% | Keeps most sessions multi-page so internal navigation gets exercised |
| Dwell time | 15–45 seconds | Long enough for scroll-depth and engagement events to fire |
| Device rate | 50/50 split | Tests desktop and mobile templates in the same run |
| Countries | Your top 3–4 markets | Catches geo-conditional redirects, banners and consent variants |
| Referrer URLs | Search plus one referral source | Validates that channel classification survived the move |
| Duration | 24–48 hours | Covers a full daily cycle including cache warm and purge windows |
The geo setting earns its place more often than people expect. Consent banners, currency switches and country-level redirects are among the most common causes of region-specific tracking loss, and they are invisible from a single office IP.
How long should you keep validating after the switch?
Longer than most teams do. The first-hour check catches catastrophic failures, but migrations keep producing tracking regressions for weeks as the backlog of small fixes ships. A CSS change breaks a click selector. A performance optimisation defers the tag past the point where a fast bouncer is counted. A redirect rule gets tightened and starts eating query strings.
A reasonable cadence is a full validation run on cutover day, a repeat at 72 hours once the post-launch fixes have landed, and then a light weekly run for the first month. Keep the campaign configuration identical each time so the numbers stay directly comparable — the value of a control is that it does not change.
What do teams usually get wrong?
Four mistakes account for most of the damage.
Validating only the homepage. It is the one page that always gets tagged, because it is the one page everyone checks. It tells you almost nothing about the other forty templates.
Testing without writing down the expectation first. If you look at the report before you commit to a number, you will find a way to rationalise whatever you see. Expected values must be recorded before the run, not after.
Mixing test traffic into production data unlabelled. Use a separate property for staging, and either a distinguishable referrer or a defined test window on production so the QA sessions can be excluded from reporting later.
Treating the check as a launch-day task. Tracking regressions have a long tail. The regression that costs the most is usually the one that shipped in week three, after everyone stopped looking.
The takeaway
Migration anxiety comes from ambiguity. Numbers move, the cause is unclear, and the team argues about interpretation instead of acting. A controlled traffic run removes the ambiguity by giving you one variable you already know the answer to.
You cannot recover traffic you cannot measure, and you cannot trust a measurement you have never tested. Run the test on staging, run it again an hour after cutover, and keep running it while the fixes land. It is a few hundred sessions against the cost of a quarter spent chasing a drop that was never there.
