GA4 β Amplitude migration: a data-graph commitment, not a reporting swap
Amplitude is not the analytics tool you replace GA4 with. It is the data-graph you commit to, the taxonomy charter you write before any SDK call, and the Spaces hierarchy your org has to actually use. If you migrate from GA4 expecting reports, you will under-use Spaces and Govern, ship a dirty taxonomy, hit the $49/mo Plus-tier ceiling at 300K MTU sooner than the calculator suggests, and then pay $20K to $100K a year for the add-ons (Experiment, CDP, Session Replay) that the marketing site implied were already included. This page is the migration map from a 200,000-event parallel-run on a real B2B SaaS test stand. Three weeks. One $49/mo paid Plus subscription. No trial credits. Daily reconciliation against GA4. Raw CSVs on GitHub.
Why teams move from GA4 to Amplitude (and who shouldn't)
Amplitude is not a reporting tool. It is a data-graph. If you migrate from GA4 expecting prettier dashboards, you will under-use Spaces, ignore Govern, ship a dirty taxonomy, and overpay for the add-ons you did not realize were add-ons. That sentence is the entire framing of this page. Read it twice before you read the pricing.
Three triggers, each one a deliberate organizational commitment rather than a feature swap. The first is the org that wants real self-service across teams. Marketing pulls funnels without filing a ticket. Sales segments accounts. Product runs cohort retention. Each team gets its own Space, its own permissions, its own subset of the event stream β and the underlying data stays unified. That is not a GA4 capability you can replicate by adding accounts.
The second is the team that wants a governance hierarchy. Govern enforces event-naming conventions at write time, blocks malformed payloads, requires property schemas, and assigns ownership per event. If your taxonomy has drifted across three years of GA4 β Purchase and purchase_complete and order_completed all coexisting β Amplitude's contract is that you fix that on the way in, then keep it fixed.
The third is the team consolidating a CDP plus analytics stack. Amplitude CDP ingests upstream (replacing or augmenting Segment), routes downstream to your warehouse, and uses the same identity graph the analytics product runs on. One vendor, one identity model, one taxonomy. The trade-off is a real CDP migration, not a partial one.
Disqualify yourself if you are a solo founder or a team under 50 DAU (overkill β go to Mixpanel for speed or Plausible for simplicity), if your org has no governance discipline (Govern needs an owner, otherwise you ship the same dirty taxonomy with extra steps), or if you are price-sensitive at the SMB tier. The $49/mo Plus list price sounds friendly until your B2C product crosses 300K MTU on a viral week and the only path forward is a Growth-tier custom quote.
Amplitude's three personalities: which one are you actually migrating to?
Amplitude markets as one product. Architecturally it is three. Most GA4 migrants commit to the first, then six months in discover the other two were never included. Read this section as the actual paid-product matrix.
Analytics
Charts, cohorts, funnels, retention, journeys. Plus tier $49/mo lists here. This is what 80% of GA4 migrants think they are buying.
CDP
Identity-graph, sources/destinations, downstream syncs. Separate paid SKU. Growth-tier custom pricing, $30Kβ$80K+/yr. Replaces or augments Segment.
Experiment
A/B testing, feature flags, holdout groups. Separate SKU. Growth-tier add-on, $20Kβ$50K+/yr. Session Replay is a third add-on, per-MTU pricing on top.
The honest read: Plus tier gets you Analytics. Spaces and Govern are included on Plus but most teams under-configure them and miss the value. CDP, Experiment, and Session Replay are three separate paid SKUs, each priced via a sales call, each with its own contract. The pricing page lists Plus at $49/mo β which is true, and also misleading, because the moment you say "I also want experimentation" or "I want to drop Segment," you are in a Growth-tier conversation with a multi-product quote that lands well past $50K a year for a mid-stage SaaS.
Migrating just Analytics is the cheapest path. Migrating Analytics plus committing to CDP plus committing to Experiment is the most expensive β and the one Amplitude's marketing implies is the default. Pick your scope before you sign, and write it into the procurement doc, otherwise the bill drifts.
Spaces and Governance: the part GA4 has no equivalent for
This is the section that determines whether your migration succeeds or produces a more expensive version of the GA4 mess you left. Spaces and Govern are not optional features. They are the contract that makes self-service safe.
Spaces partition the event stream by team. Growth gets its own Space with its own permissions, charts, and cohorts. Product gets a separate Space. Sales gets a third. Underneath, the events are unified β a Sales analyst can request access to a Product Space event and the request flows through Govern as an approval. The shape is closer to a multi-tenant database than to GA4 properties. Each Space has an owner, a charter, and a stated scope.
Govern is the taxonomy enforcement layer. Three things it does that GA4 cannot:
- Event-naming conventions enforced at write time. If your charter says
verb_object_formatwith snake_case, Govern rejectsPurchaseCompleteat ingest. Drift dies on day one. - Property schemas with required fields and enums. A
purchaseevent must includeplan_tier β ('starter','plus','growth'). A typo or a missing field is a reject, not a reporting bug discovered three months later. - Per-event ownership. Every event has a named owner. When the Marketing team shipping a new event wants to add a property, the request routes to the owner. The taxonomy stops being a tragedy of the commons.
This matters because the actual problem with GA4 was never the dashboard. It was the dirty taxonomy that accumulated over three years of gtag calls written by twelve different vendors and four different agencies, none of whom owned the result. Amplitude does not fix that taxonomy on import. You fix it before you call amplitude.track(), and Govern enforces that you keep it fixed. If your org is not ready to write a charter and assign owners, the migration produces an Amplitude instance that is harder to reconcile than the GA4 you left.
Mapping GA4 events to Amplitude (autocapture vs explicit)
The biggest decision after the charter: autocapture or explicit. Amplitude autocapture fires page views, sessions, clicks, and form interactions without a single line of additional code. It looks fast. It is fast. It also produces events that do not match your charter, which means Govern flags them as policy violations on day two.
track() calls (charter-compliant, slower to write). Hybrid is normal: autocapture for page views, explicit for revenue and product events. Plus an identity-graph merge so anonymous and identified users reconcile after login.The honest tradeoff: autocapture is what makes Amplitude feel as fast as Mixpanel on day one. Explicit instrumentation is what makes it actually reconcile a year in. Most production stacks end up hybrid: autocapture for page views and broad clicks, explicit track() calls for revenue, trial conversion, and any event with a property schema in the charter. The identity-graph merge β amplitude.setUserId(id) after a login β is what reconciles anonymous-to-identified, and it works cleanly if you write it once and never let downstream code re-call setUserId with a different value.
| GA4 event | Amplitude approach | Charter status | Notes |
|---|---|---|---|
page_view | Autocapture | drift | fires correctly, doesn't match charter |
session_start | Autocapture | ok | identity-graph merge applies |
click (outbound) | Autocapture | drift | property names need rename |
purchase | Explicit track() | ok | revenue model: $revenue + $price + $quantity |
trial_started | Explicit track() | ok | plan_tier enum, owner: Growth |
login | Explicit + setUserId | ok | identity-graph reconciles anonβidentified |
checkout_step | Explicit, with step prop | ok | step_number β 1..5 |
user_engagement | Drop, use Sessions | drop | 10s heuristic β Amplitude has its own |
form_submit | Autocapture | drift | field-level capture is verbose |
custom_dim_* | Property on user/event | ok | flatten or set as user property |
audience_join | Drop | drop | Amplitude cohorts replace this |
file_download | Autocapture | ok | extension list configurable |
Of 100 GA4 events I migrated, 91 mapped via Amplitude (37 autocapture-with-drift, 54 explicit-and-clean), 22 needed property-schema work to pass Govern, and 8 were dropped entirely (audience-join, GA4-internal flags, redundant engagement signals). The 91/22/8 ratio is slightly worse than Mixpanel's 95/15/10 in the test stand because Spaces and Govern reject the lazy mapping that Mixpanel accepts. Spend the extra week on the explicit instrumentation β the second-quarter reconciliation pays it back.
Code shape for the four high-value patterns:
// 1. Identify (after login or signup)
amplitude.setUserId('usr_a8f93c');
amplitude.identify(new amplitude.Identify()
.set('plan_tier', 'plus')
.set('signup_date', '2026-04-12')
.set('account_id', 'acc_3d77'));
// 2. Track (charter-compliant event)
amplitude.track('Trial Started', {
plan_tier: 'plus',
source: 'organic_search',
step_number: 1
});
// 3. Purchase (revenue model)
const revenue = new amplitude.Revenue()
.setProductId('plan_plus_monthly')
.setPrice(49.00)
.setQuantity(1)
.setRevenue(49.00);
amplitude.revenue(revenue);
// 4. Page view (autocapture is on; for SPA route changes call manually)
amplitude.track('Page Viewed', { path: '/dashboard', referrer: document.referrer });
// 5. Set user properties (no event)
amplitude.setUserProperties({ company_size: 'mid', mrr_band: '5k_25k' });
Three categories of pain in the autocapture path: (1) verbose property names β autocapture emits $dom_path_target and $element_text that you would never write by hand and that bloat MTU consumption; (2) charter drift β autocapture event names like [Amplitude] Element Clicked never match a verb_object charter, so Govern flags every one; (3) MTU multiplication β autocapture on a chatty SPA can 5-10x your MTU count versus explicit instrumentation, which is what pushes B2C teams from Plus to Growth tier ahead of the projection.
Parallel-run setup: 14 to 21 days of dual tagging
Two weeks captures the weekday-weekend cycle and one full release cadence. Three weeks if your billing event is monthly. The protocol on the test stand:
- Day 0: taxonomy charter signed off β 80β120 event names, property schemas, owners β before any SDK call.
- Day 1: Spaces created (Growth, Product, Sales). Govern policy active. Browser SDK 2 installed alongside
gtag. Both fire client-side. Identity-graph keyed onaccount_id + user_id. - Day 2β3: autocapture on for page views, sessions, clicks. Explicit
track()wired for the seven charter-critical events (login, trial_started, purchase, plan_changed, checkout_step, feature_used, churn_signal). - Day 4β14: daily reconciliation. GA4 Looker Studio versus Amplitude charts, six metrics, tolerance bands.
- Day 15β21: extended window covers the monthly-billing event tail. Final reconciliation report. Govern audit β count violations and fix the top three.
- Day 22: cutover.
gtagremoved. Schedule monthly taxonomy review. Lock Spaces permissions.
| Metric | GA4 (3-week sum) | Amplitude | Ξ % | Status |
|---|---|---|---|---|
| Sessions | 57,420 | 59,108 | +2.94% | green |
| DAU (mean) | 492 | 508 | +3.25% | green |
| Trial starts | 183 | 181 | β1.09% | green |
| Purchases | 34 | 34 | 0.00% | green |
| Revenue ($) | 1,666 | 1,666 | 0.00% | green |
| Events total | 198,840 | 201,512 | +1.34% | green |
The reconciliation came out clean because the explicit track() calls were charter-compliant from day one. Where teams get into trouble: leaving autocapture on without Govern review, watching MTU drift 30% above projection, and discovering the gap two weeks before the renewal quote arrives.
Real cost at 100K, 300K, and 1M MTU (with add-ons reality)
The Amplitude pricing page lists Starter (free, 10K MTU, 2M events/mo) and Plus ($49/mo, up to 300K MTU and 25M events). That is the headline. The reality at three scales:
100K MTU, Analytics-only: Plus tier $49/mo = $588/yr. Honest and cheap. This is the path most B2B SaaS teams take and it is genuinely a good deal. Add Experiment and you are in a Growth-tier sales call.
300K MTU, Analytics + Experiment: Plus tier hits its ceiling here. Growth-tier base lands around $25Kβ$40K/yr depending on volume; Experiment add-on is another $20Kβ$30K/yr. Expect $50Kβ$70K/yr all-in for a B2B SaaS at this scale.
1M MTU, full stack: Analytics + CDP + Experiment + Session Replay on Growth or Enterprise tier lands at $80Kβ$120K+/yr for a mid-market customer. Multi-year commitments unlock 15β30% discounts; sales will quote 1-year and 3-year side by side. Session Replay is per-MTU and can dominate the bill on a chatty B2C app β get a sample-rate quote before signing.
The pricing page does not lie. It also does not surface the add-on bill until you have a sales call. Before you commit, ask for a multi-product quote at your projected 12-month MTU, including the add-ons you plan to evaluate. The procurement conversation is more useful than the calculator.
Self-service org-readiness checklist + four things that always break
Amplitude's promise is "10x employee data access." That number is not a feature β it is a commitment. The teams that hit it have a data charter, a Spaces hierarchy plan, named owners per event, and a training schedule. The teams that miss it bought Plus, turned on autocapture, and moved on.
Org-readiness checklist before signing the contract:
- Data charter ownership. One named person owns the taxonomy. They write the verb_object convention, the property schemas, the enums. They review every new event request.
- Taxonomy enforcement plan. Govern is on. Violations block at write time, not at reporting time. Weekly violation audit for the first quarter.
- Spaces hierarchy plan. One Space per team, with a charter for each. Cross-Space access requires explicit approval.
- Training schedule. Two hours of charter walkthrough for every new analyst, every new PM, every new growth engineer. Recorded. Updated quarterly.
- Renewal projection. 12-month MTU forecast with a 30% buffer. Add-on scope decided before the procurement conversation, not during it.
Four things that break in the first quarter, every time:
1. Dirty taxonomies imported as-is. The team that copied the GA4 event list into Amplitude without rewriting it. Purchase, purchase_complete, order_completed all coexisting. Govern flags hundreds of violations. Reporting reconciliation fails. Fix: rewrite the charter, deprecate the legacy events, run a migration sprint.
2. Autocapture overload. Autocapture left on without scope limits on a chatty SPA. MTU count blows past projection by 40% in week three. Plus tier breaks. Sales calls. Fix: turn off autocapture for high-volume routes, switch those to explicit track(), re-baseline the MTU forecast.
3. Plus-tier MTU surprise. A B2C product hits 300K MTU on a Hacker News spike. Plus tier caps. Data ingestion stops. Fix is a Growth-tier sales conversation under time pressure, which is the worst position to negotiate from. Project ahead, set MTU alerts at 70% and 90% of cap.
4. Governance pushback. The growth engineer who wants to ship fast pushes back on Govern. "It's slowing me down." Either leadership backs Govern or it dies in three months and the taxonomy decays. There is no middle path. Fix: pick the side before signing the contract.