Why Your Marketing Agency Can't Prove ROI (And What That's Costing You)
A regional vet group I talked to last quarter was spending $42,000 a month on marketing across SEO, paid search, and social. The agency's monthly report showed 1,847 "Lead" conversions. Cost per lead: $22. Looked great on the slide.
I asked one question. "How many of those 1,847 became patients?"
The room went quiet.
The agency didn't know. The vet group didn't know. The GA4 "Lead" event fired every time someone submitted a contact form, including the people pricing-shopping, the spam, the wrong-number locals, and the four people who already had three appointments booked and just wanted to ask if they could bring their cat to a dog appointment. Nobody had built the connection between that form submit and a real exam-room visit. Nobody had built the connection between an exam-room visit and revenue.
They were running a $500,000-a-year marketing engine on top of a measurement layer that couldn't tell them which half was wasted.
This is not an unusual story. It's the median story.
They were running a $500,000-a-year marketing engine on top of a measurement layer that couldn't tell them which half was wasted.
Why most agencies stop at GA4 default events
GA4's default install does about 20% of what you need. It fires page views. It fires a few automatic events (scrolls, outbound clicks, file downloads). And if your agency is on the more diligent end, they've added a custom "Lead" event on form submit. That's where most agencies stop.
Stopping there is rational, from the agency's side. The work to go further is technical. It requires a server, a data warehouse, a working knowledge of ETL, and a real conversation with the client's revenue system — which means a real conversation with the client's office manager, their PMS vendor, their accountant, and sometimes their bank. Most agencies aren't staffed to have those conversations. So the report stays at "Lead." Smart Bidding optimizes for "Lead." The dashboard shows "Lead." The check clears.
The problem is that "Lead" is not your business. Your business is closed revenue from new patients, minus the cost of acquiring them, minus the cost of serving them. The further you can move your measurement from "Lead" toward that real number, the better every downstream decision gets. The agencies that have done that work are the ones whose retainers don't churn at the 12-month mark. That's not a coincidence.
The plumbing: server-side GTM, BigQuery, revenue-event tying
Here is the part that earns the word "moat." Three pieces, working together, owned by you.
Server-side Google Tag Manager (sGTM). Instead of every analytics tag firing in the user's browser — where ad blockers, browser privacy modes, and slow networks eat 20-40% of your data — events route through a server you control (often a Cloud Run container costing $15-50/mo). Your client's first-party domain sends a single event to your server. Your server then routes that event to GA4, Google Ads, Meta, TikTok, wherever it needs to go. You get more data, cleaner data, faster pages, and a privacy story that holds up.
BigQuery as the warehouse. GA4 ships with a native, free-tier BigQuery export. Every event GA4 sees lands as a row in BigQuery with a timestamp, a user pseudo-ID, a session ID, and the full event parameter payload. You can query it. You can join it. You can keep it forever, instead of relying on the GA4 UI's sampled, retention-capped reports.
Revenue-event tying. This is the part most agencies skip. You take the client's actual revenue data — from their practice management system, their POS, their CRM, their accountant's CSV export, whatever exists — and you join it to the BigQuery event stream on a common key. Usually that's a hashed email, a phone number, or an internal customer ID. Once that join is in place, every marketing event in BigQuery can be tied, with a query, to a real dollar.
That's the loop. Cookieless server tracking → durable warehouse → real revenue join. Once it's running, the question "which channel produced which dollar?" stops being a guess. It's a query.
Once it's running, the question "which channel produced which dollar?" stops being a guess. It's a query.
What changes when you own the plumbing
Three things change immediately. None of them are subtle.
Bid strategies get smart. Google Ads' Smart Bidding is only as smart as the conversions you feed it. Feed it "Lead" — form submitters — and it bids hard for form submitters, including the wrong ones. Feed it "New Patient Visit, $385 first-visit value" via offline conversion upload from BigQuery, and it bids hard for the people who become patients. Real campaigns I've watched make this switch see CPA drop 30-50% in 60 days without changing copy or creative. The platform was always able to learn. You weren't feeding it real food.
You can kill what's not working without an argument. When a channel isn't producing revenue and you've got the query to prove it, the conversation with the client (or with your own team) stops being a debate about "branding value" and starts being a decision. Sometimes the answer is still "keep running it" — for reasons that aren't bottom-of-funnel. But you make that call deliberately. You don't make it because nobody could tell you the truth.
You stop paying for the same lead twice. Without revenue-event tying, you can't see when paid search and organic and social are all claiming credit for the same patient. With it, the math gets honest. You don't fire channels — you rebalance them. Most clients are over-indexed on the channel that's easiest to measure (paid) and under-indexed on the channel that's hardest (organic + content + AI overviews). The data fixes that.
A multi-loc vet hypothetical
A six-location vet group, $4.2M annual revenue, spending $42K/mo on marketing across organic, paid search, and paid social. Before plumbing: "Lead" CPA of $22. Lead-to-patient close rate unknown. True CAC unknown. Smart Bidding optimizing for form submits.
After plumbing — sGTM + BigQuery + a nightly join against their PMS revenue export:
- True new-patient close rate from web Lead is 31%. From phone call (via dynamic call tracking) is 64%.
- True CAC for paid search drops from "we have no idea" to $94 per new patient.
- True CAC for paid social was $387 per new patient. The agency had been reporting it at $19 per "Lead." Same dollars, different denominator.
- Within 90 days of feeding real new-patient conversions to Google Ads, paid search CAC drops 38% to $58, with no change in spend.
- Paid social budget gets cut 70%. Saved spend rotates to a content + organic pillar plan. Six months later, organic-attributed new patients exceed paid-attributed for the first time in their history.
These are not unusual numbers when the measurement layer gets fixed. They're what the median engagement looks like when an agency takes the warehouse work seriously.
The cost of staying blind
Here is the part nobody on the agency side wants to say out loud. If your agency can't prove ROI to the row-level, your agency is being paid to perform an activity, not to produce a result. That's a sustainable business — for the agency. It is an expensive business for you.
The cost compounds three ways. First, the wasted spend itself: typical engagements I audit have 25-40% of paid budget running on the wrong objective because of bad conversion data. Second, the missed reallocation: dollars that should have moved to the higher-ROI channel three quarters ago. Third, and largest, the lost compounding from content and SEO and email investments that nobody could justify because nobody could measure them. Marketing budgets get pulled from exactly the channels that compound, in exactly the years they would have compounded, because the agency doing the work couldn't show the line going up.
The clients who fix the measurement layer don't usually spend more. They spend the same dollars on different things and watch the same dollars produce twice the revenue. That's the unsexy truth.
Your agency is being paid to perform an activity, not to produce a result.
What to do this quarter
If you're paying an agency $5K/month or more and the monthly report still shows GA4 "Lead" as the headline number, you have a measurement debt. It might not be your agency's fault — most weren't built for this. But it is your problem.
Three concrete steps:
1. Ask your agency where the BigQuery export lives, and who owns it. If the answer is "we don't have one set up" or "it's in our shared account," that's the gap. The warehouse should be in your GCP project, with your billing account, with your service account credentials. You own the data.
2. Ask for the query that ties a marketing event to a dollar. Not the dashboard. The query. If nobody can write it, it doesn't exist.
3. Get an audit from someone who can show you the gap in writing. That's the Emaration audit, $497 — everything you pay for is delivered and yours to keep. We'll show you which channels are over-credited, which are under-credited, what the warehouse build looks like, and what it would cost. You can take the audit and hire someone else to do the work. We're fine with that. The point is to stop flying blind.
You're going to spend the marketing budget anyway. Spend it with the lights on.
[Get the audit →](/audit)
---
Andrew Dall is the CEO of Emaration, an AI-driven digital marketing agency built around AI orchestration and measurement that survives an audit. He's a disabled US Coast Guard veteran with 21 years in IT, cybersecurity, and MSP leadership. Previous work includes 1,000%+ organic traffic growth at MeetGreen and revenue growth from $2M to $5M at Upward Tech. B.S. Cybersecurity, Oregon Institute of Technology, Cum Laude.
See what's leaking on your own site.
The audit covers all six layers above — including the measurement-stack and AIO-visibility passes that tools can't run. $497. The audit and your 30 days of monitoring are delivered and yours to keep either way.
Start your audit →