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.

Connection: BigQuery Modelling: LookML Source: events table Maintenance: zero derived tables
Summarize This ChatGPT Perplexity

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.

Option A

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.

PDT lifecycle to manage
Option B

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.

Query cost per Explore use
Option C

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.

Opinionated, slow to update
Feature Decode GA4 events view PDT-backed view
LookML for a page_location dimension2 linesPDT plus a UNNEST per param
New GA4 parameter handlingAuto-detected, appears in the viewPDT and view both need updating
Refresh costDirect table queryPDT rebuild plus Explore query
Time to debug a numberView → table → doneView → PDT → UNNEST → export
Schema drift riskHandled upstreamSilent — PDT drops new params
Maintenance over a yearZeroRecurring, every GA4 release

One install. A clean source. LookML handles the rest.

  1. [ 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. [ 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. [ 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. [ 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.

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.

01

GCP

Run the Decode GA4 installer. Set destination_dataset_id to the dataset Looker will read from.

02

GCP

Create a service account with BigQuery Data Viewer, BigQuery Job User, and Storage Object Viewer on the Decode bucket.

03

Looker

Admin → Connections. Add the BigQuery connection. Upload the service account JSON.

04

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.

01

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.

02

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.

03

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.

04

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.

05

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.

06

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.

01

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.

02

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.

03

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.

Get Started on Marketplace → Read the documentation

Google Cloud Marketplace · Usage-based · No monthly minimum