Skip to content

Migrating from Google Analytics 4: a worked example ​

This guide walks through a real migration: the corporate website of a B2B software company (lead forms, resources, webinars and a blog), which ran on a GA4 property with a BigQuery export. The company and its figures are left out; the steps are the same for any GA4 property. It covers what to look at in GA4 before you move, how to import the full history, and how each GA4 setting translates in Eureka.

1. Audit the GA4 property first ​

Before importing anything, list what the property actually contains. On this site the audit found:

FindingWhy it matters for the migration
Tracking had nearly stopped for a month (a warning banner about the tag)Imported history is only as good as what was collected. Note the gap so nobody reads it as a real drop.
A created event (middle_of_funnel) used a regex that started with |It matched every page, so its history counts every page view. Re-create it correctly in Eureka; keep the imported rows for comparison only.
19 key events, only 4 with dataImport them all as key events and goals, then remove the dead ones in Eureka.
37 custom dimensions, 8 of them user-scopedMap each one with its scope so it is still usable as a dimension after the move.
Event data retention of 2 monthsGA4 explorations cannot go further back. The BigQuery export is not affected (see below).
Data-centre and 1280×720 traffic counted as humanTypical of scripted browsers and agents. Eureka classifies these separately.
(not set) as the second landing pageSessions starting with an event before the page view. Eureka's Setup health flags the same pattern.

Eureka runs most of these checks for you once the tag is live: see Setup health.

2. Import the full history from BigQuery ​

GA4's data retention setting (2 or 14 months) applies to explorations only. The daily BigQuery export tables (events_YYYYMMDD) keep everything since the export was linked. On this property that is every day since December 2020, while GA4 itself could only explore the last 2 months.

The import job, in short:

yaml
import_id: corporate-site-ga4-history
property_id: env:AH_PROPERTY_ID
mapping: ga4
mapping_profile: corporate-site         # custom events, custom dimensions, key events -> goals
source:
  type: ga4-bq
  project: <gcp-project>
  dataset: analytics_<property-id>
  location: europe-west1                 # the dataset's region
  include_intraday: false
  maximum_bytes_billed: 20000000000      # cost guard, per day
  time_zone: America/New_York            # must match the Eureka property
  currency: USD                          # must match the Eureka property
date_range: {start: 2020-12-08, end: 2026-10-30}
privacy:
  user_id_salt: env:AH_IMPORT_SALT
  • Time zone and currency: GA4 cuts its daily tables on the property's time zone and stores revenue in the property currency. Create the Eureka property with the same values (here New York and USD), or daily totals will not line up.
  • Cost: the importer reads one daily table per query, never the events_* wildcard, with a byte limit per query.
  • Re-runs: event IDs are derived from the source content, so re-importing a day replaces it without duplicates.

A mapping profile is a per-property section of the GA4 mapping file (importers/mappings/ga4.yaml, under profiles:); the repository ships the profile and job of this example. Run eureka-import plan first. Its coverage report lists every field found in the export and where it lands. Then run the import over the whole period. See Importing history for the full procedure.

3. Translate the GA4 configuration ​

eureka-import definitions --config job.yaml prints what the mapping profile creates in Eureka. Send it to the Admin API, or create the same objects in Admin.

GA4EurekaOn this property
Key eventsKey events + event goals19 key events (lead, event_registration, demo_request, pricing_request, newsletter…)
Key events used as leadsLead events with a stagelead, contact, newsletter… = new; demo_request, pricing_request, free_trial = qualified; purchase = converted
Custom dimensions, event scopeCustom definitions, scope event; the parameter is kept in the event's propertiespage_category, pageTopics, ebook_name, webinar_name, A/B test campaign ids…
Custom dimensions, user scopeCustom definitions, scope user; the user property is kept on every event of the visitorcompany enrichment fields, visitor ids, login state
Created eventsCreated events, evaluated when reports run (they also apply to past data)top_of_the_funnel, bottom_of_funnel, the corrected middle_of_funnel
Calculated metricsCalculated metricsnone on this property
Data filters (Testing / Active / Inactive)Data filters, same three statesan internal-traffic filter
Data retentionData retention, in months, up to your plan's limit2 months in GA4; set at least 14 in Eureka
Redact dataRedact data (query parameters and e-mail addresses)
Report library, collectionsLibrary: published collections appear in the menu"Life cycle" and "Business objectives" collections
AudiencesSegments, listed in the Audiences report31 audiences, most of them remarketing lists

Created events in GA4 are written to the BigQuery export as their own events, so their history comes over with the import. Their definitions do not: create them again in Eureka, and fix any broken regex while you are at it.

4. Run both tools in parallel ​

Keep the GA4 tag for 2 to 4 weeks after the Eureka tag goes live: Eureka reuses the tags already on the site, so nothing has to be retagged. Over the overlap, compare sessions, users and key events day by day. Expect Eureka to show fewer human sessions: agents, scripted browsers and data-centre traffic are counted in their own actor families instead of being mixed with people.

5. What you get that GA4 did not show ​

  • Agents and bots as their own audience: action agents, indexing bots, AI readers, and mixed sessions where a person hands over to an agent.
  • Pages read by AI assistants and server-side crawler visits.
  • Setup health, which catches a broken tag, a catch-all regex or a silent key event before they distort your reports.
  • Full event-level history for as long as your plan's retention allows, from the import onwards.

Agents & humans, every visit counts!