Event parameter unnesting in BigQuery
In the GA4 BigQuery export, event_params is an array of key/value records where the value lives in one of string_value, int_value, float_value, or double_value. Reading a parameter requires UNNEST plus a key filter, and doing it carelessly multiplies rows so event counts inflate. This page explains how to unnest event parameters correctly and why the wrong join over-counts.
The nested shape
Each export row carries event_params as a REPEATED RECORD: every element has a key and a value struct, and the actual value sits in whichever typed field applies — string_value, int_value, float_value, or double_value. To read 'page_location' you UNNEST(event_params), filter to that key, and pick the right value field.
If you UNNEST without filtering to a single key, or join multiple unnests naively, each event row is duplicated once per parameter, so COUNT(*) over the result no longer counts events.
- event_params is a repeated key/value record
- Value lives in string/int/float/double_value
- Unfiltered UNNEST multiplies rows per event
Unnesting without inflation
Use a scalar subquery to pull one parameter — (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location') — so the event row stays single. Count distinct events on event-level keys (for example a concatenation of event_timestamp and the user pseudo id) rather than COUNT(*) after a join. Pick the value field that matches the parameter's type, or you read nulls.
This is a query-shape pitfall, separate from schema changes that rename or move a parameter.
How it appears in analytics and logs
An event count that balloons after adding a parameter to a query usually means an UNNEST join multiplied rows rather than the data growing.
Diagnostic use case
Extract GA4 event parameters from the BigQuery export without fanning out rows and inflating event or conversion counts.
What WebmasterID can help detect
WebmasterID exposes event properties without nested-array gymnastics, reducing the chance of an unnest mistake distorting counts.
Common mistakes
- UNNEST(event_params) without filtering to one key.
- COUNT(*) after a cross-join with parameters.
- Reading the wrong typed value field for a parameter.
Privacy and accuracy notes
Parameters can hold sensitive values if instrumented poorly; review them before exposing. This page is educational, not legal advice.
Related pages
- BigQuery intraday table schema
GA4's events_intraday_ streaming table is not always schema-identical to the finalized events_ daily table. Some fields populated after processing — certain attribution, session, or derived columns — may be empty or absent intraday. Queries written against the daily schema can fail or return nulls against intraday. This page explains intraday schema differences so real-time queries do not silently lose fields.
- BigQuery vs UI discrepancies
When GA4's BigQuery export and the reporting interface show different totals, it is usually not a bug. The UI applies sampling, data thresholds, (other) aggregation, and behavioral/conversion modeling on top of the raw event stream; BigQuery exports the unmodeled, unsampled events. Knowing which transformations the UI adds explains most gaps.
- BigQuery cost and quota limits
BigQuery on-demand pricing bills by bytes scanned, and the service enforces quotas on concurrent and daily activity. GA4 export tables are date-sharded, so a query that ignores the date suffix scans every day and runs up cost; quota limits can reject jobs at peak. This page explains how cost and quotas affect GA4 export work and how to keep scans and jobs bounded.
- Event Explorer
Inspect event parameters without writing nested SQL.
Sources and verification notes
Last reviewed 2026-06-24. Facts are checked against primary/official sources where available; uncertain specifics are marked “Data not yet verified” rather than guessed.