The Google Ads interface shows you a fraction of what Performance Max is doing, and it forgets most of it after a rolling window. Pulling Performance Max data into BigQuery is how you get the breakdowns and the history the UI won't give you.
Two ways to get the data out
- The BigQuery Data Transfer Service for Google Ads, a scheduled, no-code export that lands raw report tables in your dataset.
- The Google Ads API, more work but full control over exactly what you pull and how often.
For most teams the Data Transfer Service is the right start. It runs daily, backfills history, and gives you the same tables Google reports from.
Setting up the transfer
- In BigQuery, create a dataset to hold the Google Ads export.
- Create a Data Transfer for Google Ads, pointing at your customer id, and let it backfill.
- Wait for the first load, then explore the tables, which are prefixed like ads_Campaign_ and ads_CampaignBasicStats_.
Once it lands, a Performance Max campaign is just rows you can query, filtered by channel type.
SELECT c.campaign_name, SUM(s.metrics_impressions) AS impressions, SUM(s.metrics_clicks) AS clicks, SUM(s.metrics_conversions) AS conversions, SUM(s.metrics_conversions_value) AS value FROM `project.google_ads.ads_CampaignBasicStats_1234567890` s JOIN `project.google_ads.ads_Campaign_1234567890` c USING (campaign_id) WHERE c.campaign_advertising_channel_type = 'PERFORMANCE_MAX' GROUP BY 1 ORDER BY value DESC
What you can finally see
In BigQuery you can join campaign stats to conversion value, trend asset group performance over time, and keep the search category data that the UI drops after a few weeks.
You can also blend it with your GA4 export to compare what Google Ads claims against what actually happened on site, which is the comparison the interface will never make for you.
Where it goes wrong
- You expect channel-level splits that Google simply doesn't export for PMax, so set that expectation early.
- You forget the transfer only exports forward, so start it now to build history you'll want later.
- You double count conversions by summing across the wrong stats table, since Google ships several with overlapping metrics.
- You compare raw Google Ads conversions to GA4 without accounting for their different models, and panic at a gap that's expected.
Make it a pipeline, not a one-off
Let the transfer run daily and build a small set of modeled tables on top, in Dataform or dbt, that shape the raw exports into the campaign and asset-group views you actually report on.
Then your Performance Max reporting lives in a place you control, on your schedule, instead of in a UI that shows a slice and forgets the rest.
Which tables you'll actually use
The transfer lands dozens of tables, and most you can ignore. The workhorses are the campaign table for names and settings, a campaign stats table for metrics, and the asset group and search category tables where the PMax detail lives.
Learn those four and you can answer most Performance Max questions without ever opening the UI.
Watch the query cost
These exports partition by date, so filter on the partition column and select only the fields you need. A dashboard that scans every row on every refresh runs up a BigQuery bill fast, which is an ironic way to pay for freeing your Google Ads data.
Materialize the campaign and asset-group summaries you report on, and point your dashboards at those, not at the raw tables. It keeps the bill small and the dashboards fast, which is the whole point of owning the data.
The Google Ads interface will always hide most of Performance Max. Pulling Performance Max data into BigQuery hands you the breakdowns and the history back, so the black box becomes a table you can actually query.
Want a stronger data analyst role or a raise? Grab the FREE Product Analyst Playbook and get the exact roadmap to your next offer.
