This is a worked example, not a client result
It shows the investigation order, the finding format and the reasoning we use on real projects, built from a pattern we encounter repeatedly. The figures are illustrative. We publish client numbers only when they are real, measured, and the client has agreed to them being published.This is a worked example. It shows the audit order and the reasoning we use on real projects, built from a pattern we encounter repeatedly. The figures are illustrative. We publish client numbers only when they are real, measured and the client has agreed to them being published.
Executive summary
A B2B services company reported roughly 38% more conversions in GA4 than leads in their CRM. The internal debate had been running for two quarters and had settled into two camps: marketing trusted GA4, sales trusted the CRM, and paid budget was being allocated on GA4.
There was no single cause. There were four, they operated in different directions, and each was individually measurable. Two days of real-action testing produced more clarity than two quarters of arguing.
Business problem
The company was spending materially on paid acquisition and optimising campaign bids towards a GA4 conversion signal. If that signal was inflated, the platform was being trained on noise. Meanwhile organic was being under-credited, which had already cost it budget in two planning cycles.
The presenting question was "which number is right". That question has no answer. The useful question is "what is each number counting, and where do they diverge".
Baseline
Rather than comparing two totals, we established every point in the chain where a record could be created, lost or duplicated:
- Server-side form submission log (the closest thing to ground truth).
- GTM container inventory: every tag, trigger and variable.
- GA4 conversion definitions and event stream.
- Ads platform conversion imports.
- CRM records, with source and landing-page fields.
- Consent management configuration and its two paths.
Investigation
- Inventory everything that collects. The GTM container held 47 tags. Nine were firing, unowned, and referenced properties that no longer existed.
- Classify every conversion definition. One conversion was defined on a thank-you page view. Another on a form-submit event. Both were active. Both fired on the same submission.
- Perform real actions. We submitted the actual forms and traced each submission through GTM preview, GA4 debug view, both ads platforms and the CRM. This is the step that cannot be replaced by reading configuration.
- Test both consent paths. Granted and denied. On denial, the container was dropping the conversion tag entirely rather than using consent mode's modelling behaviour.
- Check cross-domain. The booking flow ran on a subdomain with a separate container and no linker configuration, so a single journey became two sessions with the second one attributed to a self-referral.
- Check the CRM side. Lead source was captured in the form payload and dropped by the integration mapping for one of three form types — the one used on the highest-intent pages.
Evidence
| Cause | Direction | Contribution |
|---|---|---|
| Duplicate conversion (page view + submit event) | Inflates GA4 | +22 pts |
| Consent denial dropping the tag entirely | Deflates GA4 | −6 pts |
| Cross-domain not configured (journey split) | Inflates sessions, breaks attribution | +9 pts |
| Lead source dropped by CRM integration mapping | Makes CRM look sourceless | −34% of CRM source data |
| Unexplained remainder | — | 4 pts |
Four of the thirty-eight points remained unexplained after decomposition, and we reported it as unexplained. Some gap between a client-side measurement system and a CRM is always expected — blockers, offline paths, differing definitions. What is not acceptable is an unexplained gap of this size.
Root cause
Each individual cause had a reasonable local explanation.
The duplicate conversion existed because the page-view conversion was created during the Universal Analytics migration and the event-based one was added later by a different person, correctly, without anyone removing the first.
The consent behaviour came from following a CMP vendor's default template.
The cross-domain gap existed because the booking subdomain was launched by a different team.
The CRM mapping dropped source on one form type because that form was added after the integration was built.
The systemic root cause is that nobody owned the measurement chain end to end. Every component was somebody's job; the chain was nobody's.
Actions
- Retire the page-view conversion. Keep the confirmed submit event. Acceptance: a real submission produces exactly one conversion in GA4 and one in each ads platform.
- Reconfigure consent mode to model rather than drop. Acceptance: a consent-denied submission produces a modelled conversion, and reported traffic on the denied path is no longer zero.
- Configure cross-domain linking across the main domain and the booking subdomain, in one container. Acceptance: a full journey across both domains is one session with the original source preserved.
- Fix the CRM integration mapping for the third form type, and add source and landing page as required fields on record creation. Acceptance: 100% of new CRM records carry a source and a landing page.
- Delete the nine unowned tags after confirming nothing depends on them. Acceptance: container inventory documented, every remaining tag has a named owner.
- Publish a measurement plan defining lead, qualified lead and customer, so the definitions stop being implicit.
- Establish a monthly reconciliation with the gap reported and explained, not averaged away.
Priorities: items 1 and 4 were P0 — one was corrupting paid optimisation, the other was destroying attribution on the highest-intent pages. Both were about a day of work each.
Implementation
Staged deliberately, one change group at a time with a week between, so each change's effect on the reported numbers was attributable. Shipping all six at once would have produced a step change nobody could decompose — the same mistake that created the problem.
Result
What we measure:
- GA4-to-CRM match rate, reported monthly with the residual gap explained.
- Duplicate conversion rate, target zero on all tested paths.
- Share of CRM records with a resolvable source and landing page, target 100% for new records.
- Share of sessions with a resolvable channel, watching self-referrals fall as cross-domain is fixed.
Note what is not on that list: a claim that revenue increased. Fixing measurement does not add revenue. It changes which decisions get made, and it means the next decision is made on numbers that survive scrutiny.
What we learned
- "Which number is right" is the wrong question. Decompose the gap into named, measurable contributors and each one becomes a small fix.
- Read the configuration, then test with real actions. Every one of these four causes was invisible in the interface and obvious in a traced submission.
- Ship measurement fixes one at a time. Otherwise you cannot attribute the change, and you have recreated the original problem in a new form.
- Report the unexplained remainder. Four points stayed unexplained. Saying so is what makes the other thirty-four credible.
What happens next
Measurement drifts every time the site or the tag stack changes. The clients whose numbers stay trustworthy are the ones who added a monthly check and a release-time validation step, which catches breakage in weeks instead of quarters.
The data behind it
Where the reported numbers diverged from the CRM
Illustrative monthly figures. Each step is a system boundary where records were lost or duplicated.
Right-hand percentage is the conversion rate from the step above.
View the data as a table
| Step | Value | Conversion from previous |
|---|---|---|
| Form submissions (server log) | 1,240 | — |
| GA4 conversions reported | 1,710 | 137.9% |
| GA4 conversions, de-duplicated | 1,188 | 69.5% |
| CRM records created | 1,062 | 89.4% |
| CRM records with a source | 764 | 71.9% |
| CRM records attributed to organic | 291 | 38.1% |
Source: Illustrative reconstruction of the pattern this audit follows