Skip to content

GA4 bronze and modeling ​

The Google Analytics (GA4) source lands daily fact tables from the Data API. Each table is one stable set of dimensions. Rollups, pivots, and channel summaries belong in the warehouse (SQL or dbt), not in Skipprd.

This is not the GA4 BigQuery export. You get daily grains Skipprd can rewrite when Google revises a day, not event-level hits.

What to build on each bronze table ​

Bronze tableWarehouse work you typically do
google_analytics.audience_dailySite-wide DAU, sessions, engagement KPIs
google_analytics.audience_retention_dailyWAU / 28-day active users (date grain already)
google_analytics.traffic_acquisition_dailyChannel summary, source/medium rollups
google_analytics.traffic_campaign_dailyPaid campaign performance
google_analytics.user_acquisition_dailyNew-user acquisition by channel
google_analytics.events_dailyWeekly event trends (date_trunc in SQL)
google_analytics.content_pages_dailyTop pages and landing pages
google_analytics.geo_dailyCountry / region / city dashboards
google_analytics.demographics_*_dailyAge, gender, interest, language
google_analytics.ecommerce_items_dailyProduct revenue (needs ecommerce in GA4)
google_analytics.publisher_ads_dailyAd-unit performance (needs linked Ads)

Join on date plus the dimension columns the table already has. Do not ask the source for a different grain.

Settings that affect accuracy ​

These are easy to mix up. They do different jobs.

SettingRole
replace_partition on dateRewrite that calendar day's partition when metrics change
lookback_daysRe-pull recent days Google may revise
processing_lag_daysSkip the newest days while GA4 is still incomplete
window_in_daysDays per API request. Leave at 1 to limit sampling

Run a scheduled skipprd sync. Raise lookback_days when attribution windows are long. Do not raise window_in_days to speed up a backfill — that increases sampling.

See How sources land for why replace_partition is required here.

Next steps ​