The GA4 to BigQuery export is free on standard properties, takes about ten minutes to switch on, and most teams that would benefit from it have never turned it on. It’s also the answer to a surprising number of “GA4 can’t do that” complaints.

What the export actually is

Once linked, GA4 writes your raw event data into a BigQuery dataset. One table per day, events_YYYYMMDD, with one row per event and a nested event_params field carrying the parameters.

This is not a copy of GA4’s reports. It’s the raw event stream those reports are built from — before sampling, before thresholding, before the interface’s cardinality limits collapse your long tail into (other).

The four questions it answers that the interface cannot

Anything beyond the UI’s aggregation limits. GA4’s reports collapse high-cardinality dimensions into (other) once you exceed the row limits. In BigQuery every value is there.

Unsampled analysis over long windows. Explorations sample once you cross a threshold. SQL over raw tables does not.

Custom attribution. GA4 gives you its models. If you want to build a positional model with your own rules, or compare against your CRM’s view of the same conversions, you need the event stream and a query.

Joining GA4 to your own data. This is the big one. Once GA4 events sit next to your orders table, your subscription table, or your CRM, you can answer “what did this channel produce in actual revenue, net of refunds and churn” — a question GA4 alone structurally cannot answer, because it doesn’t know what happened after the conversion.

The traps

  • It is not retroactive. The export starts collecting the day you enable it. There is no backfill. This alone is a reason to turn it on before you think you need it — the cost of having it and not using it is roughly zero.
  • Daily vs streaming. The daily export lands events_YYYYMMDD once a day, usually with a lag. The streaming export writes events_intraday_ continuously and costs more. Most teams need daily; check which one you enabled before debugging “missing” data.
  • The nested schema surprises people. event_params is an array of key-value structs, so a naive SELECT * is not going to give you a flat table. You unnest it. Every GA4 BigQuery tutorial spends its first section on this for a reason.
  • user_pseudo_id is not a person. It’s a device-and-browser identifier. Cross-device analysis requires a user_id you set yourself.
  • Numbers will not match the GA4 UI exactly. The interface applies its own modeling, thresholding and attribution on top of the raw data. Small deltas are expected; large ones mean a real problem worth finding.

When it stops being optional

You need this once any of the following is true:

  • Marketing decisions depend on revenue data that lives outside GA4.
  • Your conversion volume is high enough that sampling affects the numbers you present.
  • Someone is asking attribution questions GA4’s built-in models don’t answer.
  • You need history longer than GA4’s retention window, which caps at 14 months for user-and-event-scoped data on standard properties.

That last point catches people. GA4 will quietly stop being able to answer year-over-year questions, and the export is the only way to keep the raw history.

The practical recommendation

Turn it on now, even if nobody queries it for six months. It’s free, it takes ten minutes, and the data it collects starting today is data you cannot get retroactively. Treat it as insurance on your own history.

If your measurement setup is the thing that isn’t adding up, see how I work with brands — tracking is usually the first thing I audit.