The problems we solve
Google Ads data is easy to look at and hard to report on — the
numbers keep moving, the formats fight you, and the join to your
analytics is on you. These are the problems this pipeline is built
around.
How do you join Google Ads cost with GA4 sessions?
Out of the box, you don’t — spend lives in one silo and sessions in another, and the join is on you. It needs campaign keys that actually match, UTM conventions that survive renames and both sides landed in the same database at the same grain. Most teams settle for eyeballing two dashboards instead.
We build that join into the data models: campaign names parsed into market, product and funnel-stage columns, keys aligned with your GA4 session models, and cost sitting next to the sessions and revenue it bought. That’s the foundation a real cost-per-acquisition number stands on.
Which CPA is the true CPA — Google Ads or GA4?
They will not agree, ever. Different attribution models, different count dates (Google Ads writes conversions back to the click date, GA4 counts events on the day they happen), different visibility into the journey. Neither is broken, and picking one at random just moves the argument to next quarter.
The data models put both next to each other in clearly labelled columns, computed over the same spend rows — which turns a recurring argument into a known, stable difference you can decide against.
Why do last week’s Google Ads conversions keep changing?
Conversion lag. A click today can convert next week, and Google writes that conversion back onto today’s row. Any export that pulls each day once diverges from the interface within days.
The pipeline’s rolling re-sync window exists precisely for this — recent days are re-pulled until they stop moving, so the data models converge on final numbers instead of freezing the early ones.
Why is the native Google Ads transfer so hard to query?
The BigQuery Data Transfer lands dozens of fixed report tables — campaign, ad group, ad, a family of *Stats tables — with cost serialized as micros: millionths of the account currency, as ten-digit integers. Forget the division once and a dashboard reports a million times the spend.
The transfer is a delivery mechanism, not a model. We treat it as one: normalization, rounding policy and currency conversion happen in the pipeline, and what your team queries are data models where cost is simply money.
Why don’t search terms sum to campaign totals?
Two reasons. Google withholds low-volume search terms for privacy, so the search-term report is a large sample, not a census. And the terms aren’t in the native transfer at all — they exist only on the API route, which is why transfer-only setups never see them.
We pull search terms through the API alongside whichever route carries the rest, and the data models record both levels so the withheld share is a measurable number, not a suspicion.