Cross-platform ad attribution without Looker
You don't need a $40k/year BI tool to know which ad dollars are working—here's the exact minimum stack that gets you 90% of the answer.


Most founders who come to us with attribution problems don't have a data problem. They have a tooling debt problem: they bought Looker (or Tableau, or a custom dbt pipeline) before they had stable enough spend or consistent enough naming conventions to make any of it work. The dashboards are beautiful. The numbers are wrong.
The dirty secret of cross-platform ad attribution is that the complexity doesn't compress the uncertainty—it hides it. A well-maintained spreadsheet with the right attribution window settings will outperform a beautiful BI dashboard built on mismatched windows every single time.
TL;DR — Cross-platform attribution without Looker
- Last-click attribution across Google, Meta, and TikTok is broken by design, but a UTM-plus-spend pull into one spreadsheet gets you to "good enough" decisions in under a day of setup.
- The minimum viable attribution stack is: consistent UTMs → GA4 (or equivalent) → a single manual or API-pulled spend sheet → one calculated ROAS/CPA column per channel.
- You need Looker (or a real warehouse) only when you're reconciling more than three platforms, running holdout tests, or your spend is high enough that a 5% misattribution costs real money.
- The biggest attribution error founders make isn't choosing the wrong model—it's using different attribution windows on different platforms and comparing the numbers directly.
- We built a lightweight pipeline that pulls spend plus conversion data into a single normalized table without a warehouse; the design principles are reusable even if you don't use our product.
Attribution windows are the real problem, not the tool
Before you buy anything, name the actual failure mode. Ninety percent of the time when a founder says "my attribution is broken," what they mean is: Meta says a campaign drove 80 conversions this week, Google says it drove 60, and GA4 says 40. The total is implausible.
That gap is almost never a tooling gap. It is an attribution window mismatch.
Meta's default is a 7-day click plus 1-day view window. Google Ads defaults to a 30-day click window for most conversion actions. GA4's session-based model counts the session that included the last click before the conversion. These three numbers are measuring genuinely different things. Dropping them into the same Looker dashboard does not resolve the difference—it just makes it look like a number instead of a question.
Before you touch any tool, set every platform to the same attribution window. We use 7-day click, 0-day view across all channels. You will lose some reported conversions. You will gain comparability.
Exact window settings per platform
Here is where to make the change on each major platform, and what to watch for:
Google Ads — Navigate to Tools → Conversions → select a conversion action → Edit settings → Attribution model and Conversion window. Set click-through window to 7 days. Set view-through window to 0 days (the minimum Google allows is 1 day for view-through; set it to 1 and then exclude view-through from your comparison columns). Also check whether your conversion actions are set to count "Every" or "One" conversion per click—for purchase goals, "One" is almost always correct. Google's attribution documentation covers all conversion counting options.
Meta — In Events Manager, select your pixel → Settings → Attribution settings. Change the default from 7-day click plus 1-day view to 7-day click only. This affects how Ads Manager reports conversions in every campaign view. Note that Meta's API also returns data under the old window setting if you don't specify the attribution_setting parameter in your pull—check your connector. Meta's attribution setting guide shows the exact path.
TikTok Ads — In TikTok Ads Manager, go to Campaign → Ad Group level → Attribution. The default is 7-day click plus 1-day view, same shape as Meta. Set to 7-day click only. TikTok's view-through attribution is aggressive; leaving it on inflates reported conversions substantially for awareness-heavy campaigns.
LinkedIn — Campaign Manager → Conversions → select a conversion → Attribution window. Default is 30-day post-click, 7-day post-view. Set post-click to 7 days, post-view to 0 days if your goal is cross-platform comparability.
Do this first. It costs nothing and fixes more than any tool.
The minimum viable attribution stack
Here is the exact stack we recommend for teams spending between $5k and $100k/month across two to four paid channels:
Layer 1 — UTM discipline
Every ad, every platform, every campaign gets a UTM string with at minimum: utm_source, utm_medium, utm_campaign, and utm_content. The content parameter carries the ad creative ID so you can tie creative performance back to spend later. This is unglamorous and it breaks every time someone boosts a post without tagging it, but it is non-negotiable.
Layer 2 — One destination for events
GA4 is free and sufficient for most teams under $50k/month in spend. The goal is a single place where conversion events (purchases, signups, qualified leads) are recorded with the UTM source attached. If your conversion happens off-web (phone call, in-store), you need a different first-party signal, but the principle is the same: one canonical event log.
Layer 3 — A spend pull
This is where most "simple" attribution stacks fall apart. You need spend data from each platform next to your conversion data. The options from cheapest to most complex:
- Manual weekly export from each platform into a shared sheet. Tedious, error-prone, works fine at low volume.
- A connector tool (Supermetrics or Windsor.ai) that pulls spend into Google Sheets on a schedule. Costs roughly $50–200/month. Removes the manual step.
- Direct API pulls into a database. Right move at scale, overkill under $50k/month.
Layer 4 — One calculated table
Channel | Spend | Conversions (GA4) | CPA | Platform-reported CPA | Delta
That delta column is your signal. When Meta's reported CPA is 40% lower than your GA4-derived CPA, something is wrong: overlapping windows, view-through inflation, or a broken pixel. The spreadsheet surfaces it. Looker would display it more prettily but wouldn't explain it.
We have seen teams discover that an entire Meta campaign's reported conversions were almost entirely view-through attributed—meaning Meta was claiming credit for users who saw an ad once and then converted via a Google search days later. The platform-reported CPA looked great. The GA4-derived CPA was three times higher. The spreadsheet delta made this obvious in five minutes.
Why a spreadsheet is enough at first
The argument for starting with a spreadsheet is not that spreadsheets are good. It is that the constraints of a spreadsheet enforce clarity that BI tools actively undermine.
In a spreadsheet, every formula is visible. You cannot accidentally join on the wrong key without noticing. When your spend sheet has 12 rows (one per campaign) and your GA4 export has 11, you will immediately ask why. In Looker, that same join silently drops a row and your dashboard still loads.
The forcing function is also temporal. A spreadsheet you update manually, even weekly, keeps you close to the raw numbers. You develop intuition about what normal looks like. When a number is wrong, you notice faster.
The practical ceiling for a spreadsheet attribution model is roughly: three to four platforms, fewer than 200 active campaigns, weekly rather than daily decision cadence. If your business is inside those bounds, the spreadsheet is not a compromise—it is the right tool.
The teams we've seen struggle most with attribution are the ones who stood up a warehouse at $30k/month before their UTM naming was consistent. They had impressive infrastructure and unreliable data. The teams who waited until they felt real pain from the spreadsheet constraints—campaigns multiplying, stakeholders colliding in the same tab—arrived at their warehouse with clean naming conventions and a clear model of what they needed to answer. The infrastructure served the question rather than preceding it.
When you actually need Looker
There are four real reasons to graduate to a proper BI stack:
1. More than three platforms with different data shapes. When you're pulling from Google, Meta, TikTok, LinkedIn, and a programmatic DSP, the schema differences are painful enough that a transformation layer (dbt or similar) earns its keep.
2. Holdout and incrementality testing. If you're running geo-based holdout tests or conversion lift studies, you need to join experiment assignment data against conversion data at row level. Spreadsheets can do this, but it becomes fragile fast.
3. Spend above the threshold where 5% misattribution is real money. At $20k/month, a 5% error is $1k. At $500k/month, it's $25k. The cost-benefit of better tooling changes at that scale.
4. Multiple stakeholders who need to slice data independently. If five people need to filter the same attribution data by different dimensions daily, a shared spreadsheet becomes a collision problem.
Notice what's not on this list: "it would be nice to have prettier charts." That is not a reason.
If you do graduate to a warehouse, the stack we've seen work well at the $100k–$500k/month range is: Fivetran or Airbyte for extraction → BigQuery or Snowflake for storage → dbt for transformation → Looker or Metabase for visualization. The dbt documentation on staging models is the best single resource for understanding how to structure the transformation layer.
What we built
We ran into this problem ourselves while building the multi-platform management layer in AdControlCenter. We needed a unified spend plus performance view across Google and Meta that didn't require our users to have a warehouse.
The solution we shipped pulls spend and impression data from each platform's API on a 6-hour schedule, normalizes it into a single schema (date, platform, campaign_id, campaign_name, spend, impressions, clicks, platform_reported_conversions), and writes it to a Postgres table we expose via a simple read endpoint. Users connect that endpoint to their own GA4 or Segment data using a lightweight join key we generate from the UTM campaign parameter.
The design principles we learned:
- Normalize campaign names before you store anything. "BRAND_AWARENESS_META" and "brand-awareness-google" are the same campaign strategy. Build a slug function that lowercases and strips platform identifiers before storing campaign names.
- Store raw and normalized separately. We keep the raw API response frozen so we can re-derive anything if a platform changes its attribution model retroactively. Meta has changed its default attribution window at least once since 2021, and having the raw response meant we could reconstruct historical comparisons correctly.
- Make the join key explicit, not inferred. We generate a
campaign_slugfrom UTM parameters. We do not try to fuzzy-match campaign names across platforms. Fuzzy matching breaks silently. - Surface the delta, don't hide it. Our UI shows platform-reported conversions next to GA4-derived conversions by default. When they diverge by more than 20%, we flag it. Most BI tools show you one number and let you pick which source. That is the wrong default.
The infrastructure costs less than $10/month. For most teams under $200k/month in spend, it answers "which channel is driving real conversions this week" well enough to make budget decisions.
FAQ
What is the simplest way to do cross-platform ad attribution?
Set identical attribution windows (7-day click, 0-day view) on every platform, tag every ad with consistent UTMs, funnel all conversion events into GA4, and pull spend from each platform weekly into a single spreadsheet. Calculate CPA per channel using your own conversion data, not the platform-reported number. That four-step process handles most of what a full BI stack handles for teams under $100k/month.
Why do Meta and Google report different conversion numbers for the same campaigns?
They use different attribution windows by default, different counting methods (Meta counts all conversions in the window; Google can be set to count one per click), and different identity graphs. Meta's view-through attribution also claims conversions that other platforms don't count. Set both to 7-day click, 0-view before comparing anything.
Do I need a data warehouse for ad attribution?
Not until you're managing more than three to four platforms simultaneously, running holdout tests, or spending enough that small attribution errors represent real budget decisions. A well-maintained spreadsheet connected to GA4 is accurate enough for most teams under $100k/month.
What UTM parameters are required for cross-platform attribution?
At minimum: utm_source (the platform), utm_medium (paid-social, paid-search, etc.), and utm_campaign (maps to a campaign in your spend sheet). Add utm_content if you want to tie creative performance to spend. The campaign value must match exactly what you use in your spend pull—casing and spacing differences will break your joins.
What is the difference between first-touch, last-touch, and data-driven attribution?
First-touch gives 100% credit to the first ad a user interacted with. Last-touch gives 100% credit to the final ad before conversion. Data-driven (available in Google Ads and GA4) uses statistical modeling to distribute credit across touchpoints. For most founders, last-touch is the practical default because it's what platforms report and what GA4 measures by default. Data-driven is worth using when you have high enough conversion volume for the model to be statistically valid—.
Can I do attribution without GA4?
Yes. Any first-party event log that captures UTM parameters at conversion time works. Segment, a custom database table, or even a form submission log that writes UTM values to a row is sufficient. GA4 is the default recommendation because it's free, it handles UTM parsing automatically, and its API is well-documented. The principle—one canonical conversion log with source data attached—matters more than the specific tool.
What is incrementality testing and when do I need it?
Incrementality testing measures what would have happened if you hadn't run an ad—your true lift. Attribution models (including data-driven) can only allocate credit among the ads a user saw; they can't tell you whether the user would have converted anyway. You need incrementality testing when you suspect your last-touch attribution is overcounting branded search conversions or retargeting, or when you want to validate whether a channel is actually driving new demand. It requires holdout groups and meaningful sample sizes, which is why it's a later-stage investment.
The specific takeaway: before you spend a day evaluating BI tools, spend two hours normalizing your attribution windows across every platform using the exact settings above, then re-pull last month's numbers. If the answer to "which channel has the lowest real CPA" changes, you've already fixed your biggest attribution problem—and it cost you nothing.

We build AdControlCenter — AI-powered ad management for anyone running their own ads. We write what we'd want to read: real numbers, no fluff, the things we wish we'd known when we started.
More from the team →Keep reading
All posts →
Budget splits for $500 / $1k / $2k / $5k monthly
The platform you add second matters more than the total you spend — here's exactly how to split your ad budget at every stage from $500 to $5k/mo.

Running Paid Ads Across Google, Meta, Reddit, and TikTok as a Solo Founder
A 90-minute weekly routine for running multi-channel paid ads alone, without an agency, without burning out, and without lighting your budget on fire.

High CTR, Zero Sales: How to Find the Real Bottleneck in Your Funnel
A high CTR means the ad worked — it doesn't mean the funnel did, and confusing the two is the most expensive mistake in paid search.