Business

The GA4 Migration Checklist: Leaving Without Losing History

Six steps to leave Google Analytics 4 with your history archived, your events mapped, and your stakeholders still trusting the numbers.

August 2026 • 9 min read

Leaving GA4 is not hard because the new tool is hard. It is hard because GA4 holds years of your history hostage to retention windows, export limits, and a data model nothing else shares. A migration that starts with "install the new tag" and ends with "delete the old one" will lose data in between.

This GA4 migration checklist is the version that doesn't. Six steps, in strict order, because the order is the point: you export before you install, you overlap before you compare, and you compare before you delete. If you want the deeper product comparison first, read ClickStream vs GA4; this page is the operational plan.

Why You Need a GA4 Migration Checklist at All

Two properties of GA4 make an unplanned exit expensive:

The cost of migrating off GA4 is mostly the cost of what you failed to export before you started. Everything else is just work.

Step 1: Export Everything GA4 Will Give You

Do this first — before installing anything new — because some exports only capture data going forward.

Link the BigQuery export immediately

GA4's BigQuery link is the only way to get raw event-level data out, and it only collects from the day you link it — there is no backfill. Even if you are leaving Google entirely, link it now so the months between decision and decommission are captured at full granularity. Daily export caps apply on the free tier, and querying the data requires a Google Cloud project, but a raw archive you own beats aggregates you don't.

Export the reports you actually use

You will not export everything, so export what people reference:

Document what can't be exported

Audience definitions, key-event configurations, custom dimensions, and attribution settings don't export as data — capture them as documentation (screenshots and a spreadsheet are fine). You will need them in Step 2, and they disappear with the property.

Step 2: Map Events to a Clean Taxonomy

Most GA4 properties accumulate years of taxonomy debt: purchase, Purchase, and purchase_new_v2 coexisting peacefully. Migration is the one moment you can fix this without breaking historical comparisons, because the comparison line breaks anyway.

Inventory your events in four buckets — auto-collected, enhanced measurement, recommended, and custom — then map each to a deliberate convention. In ClickStream's case, standard interactions (page views, scrolls, clicks, form submits, file downloads, video plays) are auto-captured, so the mapping burden falls almost entirely on custom events:

GA4 Event Migration Action
page_view, scroll, click, form_submit, file_download Auto-captured — no mapping needed
gtag('event', 'purchase', {value: 99}) window.clickstream.trackEvent({name: 'purchase_completed', value: 99})
gtag('event', 'sign_up', {method: 'email'}) window.clickstream.trackEvent({name: 'sign_up', label: 'email'})
gtag('config', ..., {user_id: ID}) window.clickstream.identify(user.email)

ClickStream event names are free-form strings, so the naming convention is yours to define — define it once, in writing, before anyone ships a tag. The same discipline applies to campaign parameters: if your UTMs are inconsistent, fix them in the same sprint (see the UTM taxonomy guide for conventions that survive growth).

Step 3: Run Parallel Tracking During Cutover

Never hard-cut an analytics migration. Run both systems side by side for at least two to four weeks — ideally one full business cycle — so you have overlapping data to validate against.

The two tags coexist safely. GA4 sets and reads its own _ga cookies through gtag.js; ClickStream ships a 344-byte loader that pulls a ~56.5 KB gzipped bundle from your own subdomain and relies on its own server-set first-party cookie. Neither touches the other's cookies, globals, or events — they observe the same pages independently:

<!-- Existing GA4 tag (keep this for now) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>

<!-- Add ClickStream below -->
<script src="https://t.yourdomain.com/sdk.js" data-key="cs_live_xxxxxxxxxxxxxxxxxxxxx" async></script>

Before the tag goes live, point a CNAME subdomain at ClickStream so cookies are set server-side on your own domain — our implementation guides cover the DNS setup, and the install page covers script-tag, NPM, mobile, and server options. The overlap period costs nothing to start: the Hobby tier is free for 50,000 human pageviews a month, no card required (see pricing).

Step 4: Validate — Your Numbers Will Not Match, and That's Expected

The most common migration failure isn't technical. It's a stakeholder looking at two dashboards, seeing different numbers, and concluding the new tool is broken. Set the expectation up front: no two analytics systems report the same numbers, because they disagree about what to count before they ever count it.

Why numbers differ GA4 ClickStream
Bot filtering Silently excludes known bots; you can't see what was removed Classifies bots across 11 categories (158 named bots, 38 AI agents), shows them, and excludes them from billing — you're billed on human pageviews only
Sampling Explorations sample above ~10M events per query; user counts are approximated No sampled scoring — every event processed at ingest
Identity & cookies JavaScript-set cookies capped at 7 days by Safari ITP; users modeled via Google Signals / User-ID Server-set first-party cookie persists ~400 days (the browser maximum), so more returning visitors are recognized
Session definition 30-minute inactivity timeout plus its own engaged-session rules 30-minute inactivity timeout; definitions differ enough to shift session counts
Processing latency Reports can lag 24–48 hours Real-time; scores computed at the edge (p95 under 3 ms per event in a CI-enforced benchmark)

During the overlap, document each delta and its cause. Expect ClickStream to report more unique returning visitors (longer-lived cookies recognize people GA4 forgets) and fewer "new" ones, and expect visible bot traffic GA4 never showed you. Then agree acceptance criteria with stakeholders before cutover: not "the numbers match," but "the deltas are stable week over week and each one is explainable." That's what a trustworthy migration looks like. If bot volume surprises anyone, that conversation matters beyond analytics — it distorts A/B tests and paid-media metrics too.

Step 5: Redirect Dashboards and Reports

Analytics data has consumers, and they don't migrate themselves:

  1. Inventory every consumer of GA4 data — Looker Studio dashboards, scheduled email reports, spreadsheet pulls, board decks, agency reports. If a number appears anywhere monthly, find its source.
  2. Rebuild each report in the new platform, mapping to equivalent metrics rather than chasing identical values.
  3. Annotate the cutover date on every long-running chart. A trend line that silently switches measurement systems mid-series will mislead someone within a quarter.
  4. Keep GA4 read-only during transition so people can answer "what did we report last March" from the old system while the new one accrues history.

For warehouse users: ClickStream offers self-serve CSV export on Growth+ plans, and raw-event Parquet export (BigQuery/Athena/DuckDB-compatible) on request on Scale+ — so your archived GA4 BigQuery data and your new event stream can eventually sit side by side in the same warehouse.

Step 6: Decommission GA4 Cleanly

Once stakeholders have signed off on the new source of truth:

What Does Not Migrate — Being Honest About It

No platform, ClickStream included, can import your historical GA4 raw events as if they were natively collected. The data models are fundamentally different — GA4's event schema, session logic, and identity spaces don't translate into another system's without producing numbers that are neither GA4's nor the new tool's. Anyone who promises a lossless historical import is promising something the data can't support.

What you keep instead: your BigQuery archive (raw events, queryable forever), your CSV aggregates (trend continuity), and your parallel-tracking window (the bridge between measurement eras). That combination answers virtually every real question — "how did last year compare" comes from the archive; "how are we doing now" comes from the new system; the overlap explains the difference between them.

The new history you accrue is also structurally different. With server-set first-party cookies persisting ~400 days, cross-session identity survives in ways GA4's 7-day JavaScript cookies never allowed — the mechanics are covered in first-party cookie persistence. And if you're still choosing a destination, the honest guide to Google Analytics alternatives compares the field beyond ClickStream.

The Bottom Line

A GA4 migration succeeds in the ordering: export first, map deliberately, overlap before comparing, compare before deleting. Teams that follow the sequence keep their history, their taxonomy improves in transit, and their stakeholders trust the new numbers because every delta was explained rather than discovered. Teams that skip Step 1 find out what the retention window meant.

For the week-by-week implementation version of this checklist — with owners, statuses, and the full event-mapping tables — see the GA4 migration guide in our implementation docs.

Start the Overlap Today

Parallel tracking is free to begin — 50,000 human pageviews a month on the Hobby tier, no card required. Install alongside GA4 and let the data make the case.

Start free