Decoded GA4 as a LookML view —
governed metrics, no UNNEST
derived tables.
Looker is Google Cloud's enterprise BI platform. Its strength is LookML — a modelling layer that defines metrics and dimensions once and reuses them across every report. Its weakness against the raw GA4 export is that LookML expects flat columns, and the export gives you nested records. Most teams paper over this with derived tables that wrap the same UNNEST patterns dbt projects suffer from. Decode GA4 removes the derived tables. The events view references real columns.
Looker is a modelling layer first and a charting tool second. The model is only as good as the columns underneath it.
The shape of the problem
LookML defines dimensions and measures over SQL columns. Each one is a column reference plus a type. The raw GA4 export has nine real top-level columns and one repeated record that contains everything else. To define a page_location dimension, you cannot reference event_params.page_location directly — there is no such column. You write a derived table that UNNESTs event_params and exposes one column per parameter, then build the view on top of that.
Why this hurts Looker projects specifically
Two reasons. First, derived tables are expensive — they are SQL queries that run on cache miss, and large GA4 derived tables produce large refresh costs across every Explore that depends on them. Second, the LookML model becomes a wrapper around a wrapper: the view describes the derived table, the derived table reshapes the export, and the export is the actual source of truth. Anyone debugging a Look has to follow that chain backwards to make sense of a number.
What changes with Decode GA4
Decode writes a flat events table into a BigQuery dataset of your choice. Your LookML view references it directly. event_param.page_location is a real column, so the dimension is two lines of LookML. partition_date is a real column, so the date filter is built in. Derived tables disappear from the project, except where you genuinely need them for business logic.
The traditional approach
Persistent derived tables for GA4
Write a PDT that flattens events_*, schedule it nightly, build the LookML view on top. The PDT becomes the bottleneck. When it fails, every Explore that touches it returns errors. When GA4 changes, the PDT has to be updated, tested and rebuilt.
Ephemeral derived tables (no caching)
Define the UNNEST as the view's sql_table_name. Every Explore query rebuilds it. The cost per query is high, query latency rises, and Looker's caching helps less because the underlying SQL is dynamic.
A community LookML block
Adopt a public GA4 block. They tend to flatten more events than you need, ship a heavy set of measures you may not want, and lag behind GA4 schema changes. You inherit somebody else's modelling decisions and somebody else's release cadence.
Decode GA4 vs derived-table LookML
| Feature | Decode GA4 events view | PDT-backed view |
|---|---|---|
| LookML for a page_location dimension | 2 lines | PDT plus a UNNEST per param |
| New GA4 parameter handling | Auto-detected, appears in the view | PDT and view both need updating |
| Refresh cost | Direct table query | PDT rebuild plus Explore query |
| Time to debug a number | View → table → done | View → PDT → UNNEST → export |
| Schema drift risk | Handled upstream | Silent — PDT drops new params |
| Maintenance over a year | Zero | Recurring, every GA4 release |
One install. A clean source. LookML handles the rest.
- [ 1 ]
Subscribe via Google Cloud Marketplace
Decode GA4 is a Marketplace listing. Usage-based pricing, no monthly minimum. The subscription takes under a minute and billing appears on your existing GCP invoice.
- [ 2 ]
Connect Looker to BigQuery
Admin → Connections → New Connection → BigQuery Standard SQL. Upload the GCP service account JSON. The service account needs BigQuery Data Viewer, BigQuery Job User, and Storage Object Viewer on the Decode GA4 GCS bucket.
- [ 3 ]
Create a LookML project
Develop → Projects → New Project. Define a view that references decode_ga4.events. Define an Explore in the model file. event_param.page_location, event_param.page_referrer, geo.country and partition_date are all direct columns — no derived tables required.
- [ 4 ]
Deploy and use
Validate LookML, deploy to production, navigate to Explore → GA4 Events. Dimensions and measures appear in the field picker. Looks built on top inherit governance: change a measure once, every Look updates.
HOW THE SETUP WORKS
Wire decoded GA4 into a Looker project in four small steps. Nothing here is Looker-specific magic — it is the same connection-and-view pattern you already use for every other warehouse table.
GCP
Run the Decode GA4 installer. Set destination_dataset_id to the dataset Looker will read from.
GCP
Create a service account with BigQuery Data Viewer, BigQuery Job User, and Storage Object Viewer on the Decode bucket.
Looker
Admin → Connections. Add the BigQuery connection. Upload the service account JSON.
LookML
Define a view over decode_ga4.events and an Explore in the model. Deploy.
The events table is a BigQuery external table backed by Parquet files in GCS. Looker reads it through its native BigQuery connection, but the underlying storage stays in your project. No data leaves your perimeter.
What you get in Looker
A LookML view, not a derived table
The events view references decode_ga4.events directly as sql_table_name. There is no PDT to schedule, no ephemeral derived table to rebuild, no caching layer to debug.
Direct column dimensions
page_location, page_referrer, page_title, ga_session_id, geo.country, device.category — every standard parameter is a real column. Each dimension definition is a few lines of LookML.
Governed metrics, defined once
Sessions, engaged sessions, conversion events, event counts — define each measure once in LookML. Every Explore, dashboard and Look reuses the same definition.
Schema evolution that just works
When GA4 adds a new event parameter, the next decode run picks it up. Run a schema refresh on the connection (or redeploy LookML) and the new column is ready to add to the view.
Cheaper Explore queries
No PDT rebuilds, no UNNEST runs per query. Looker queries the decoded events table directly, and BigQuery scans only the partitions and columns needed.
Self-service that is actually safe
Business users build Looks in the Explore. The metrics they pick are defined and tested in LookML. There is no calculated-field wild west underneath.
Executive dashboards with one source of truth
Sessions, conversions and revenue defined as measures in LookML. Every executive dashboard reuses them. When the definition of "engaged session" changes, it changes in one place.
Self-serve marketing analytics
Explore over events with source-medium, campaign and landing-page dimensions exposed. Marketers build their own Looks against governed metrics, without writing SQL.
Product analytics on shared definitions
Custom event parameters that the product team adds — feature flag, plan tier, A/B variant — show up as columns the moment they fire. Add a dimension, redeploy LookML, the field is available across every Explore that uses the events view.
Does this work with Looker (Google Cloud core) and the original Looker?
Both. The integration is at the warehouse layer — the BigQuery connection sees the decoded events table the same way regardless of which Looker product is reading from it. See setup →
Do I need to delete my existing PDTs?
Not immediately. You can run the decoded events view alongside an existing GA4 PDT and migrate Explores one at a time. Most teams find the PDT becomes redundant once the new view is in production.
What permissions does the Looker service account need?
BigQuery Data Viewer, BigQuery Job User, and Storage Object Viewer on the Decode GA4 GCS bucket — required because the events table is an external table backed by Parquet files. Full prerequisites →
Can I still use derived tables for business logic?
Yes. The point is to remove derived tables that exist purely to flatten GA4 — not derived tables that compute something genuine, like a session-level rollup or a funnel sequence. Those are still the right tool.
Deploy in under 5 minutes
Looker over GA4,
without the derived-table tax.
Subscribe via Google Cloud Marketplace, point destination_dataset_id at your Looker connection's dataset, and have a clean events view available in LookML before the end of the day.
Google Cloud Marketplace · Usage-based · No monthly minimum