How to Backfill GA4 Data in BigQuery

Last updated August 29, 2026 · By the SaturnSQL team

You can't, natively. The export starts on the day the BigQuery link is created and Google provides no backfill of earlier events. The workaround is loading historical aggregates from the GA4 Data API into their own table.

Why there is no backfill

The BigQuery link streams events forward from the moment it is enabled; events from before that date were never written anywhere you can reach at event grain, and GA4's own retention setting governs the UI, not the export. This is the single best argument for enabling the export on day one even if you have no immediate plans for it: it is free for standard properties, storage is the only cost, and every un-exported day is gone for good.

See where your export actually starts

The earliest daily table is the hard wall for raw-event history. This lists it directly:

SELECT MIN(_TABLE_SUFFIX) AS first_exported_day
FROM `myproject.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX NOT LIKE 'intraday%';

The workaround: Data API aggregates

For history before the link date, pull aggregated reports (sessions, users, conversions by date and dimension) from the GA4 Data API and load them into a separate BigQuery table. It is aggregate-grain, subject to the API's sampling and cardinality limits, and the dimensions you did not request are lost, so keep it in its own clearly-named table rather than pretending it is event data. Query old aggregates and new raw events side by side with a UNION only where the definitions genuinely line up.

Run this in SaturnSQL

SaturnSQL is a browser-based SQL editor for teams: shared query library, schema-aware autocomplete, and scheduled exports to Google Sheets and Slack.

Try it free

Do more with BigQuery

Related BigQuery guides