Why your GA4 numbers don't match your CRM
Some of the gap is structural and will never close. The rest is implementation error. How to tell which is which, and what to report instead.
Analytics says 180 conversions last month. The CRM says 114. Someone asks which is right, and the meeting goes nowhere, because both systems are confident and neither can show its working.
The useful first move is to stop trying to make them match. Part of that gap is structural and closing it is not possible. The rest is error, and that part is worth every hour you spend on it. The skill is telling them apart.
The part that will never close
These four differences are inherent in how the systems work. No configuration fixes them.
They count different moments. Analytics records an event when a form is submitted. The CRM records a contact when a record is created, sometimes after validation, deduplication or a manual step. Between those two moments, records get merged, rejected and delayed. Both counts are correct about different things.
Consent and blocking remove people from one side only. Anyone who declines analytics cookies, uses a blocker, or browses in a privacy-focused browser can still submit your form. They exist in the CRM and not in analytics. The size of this gap varies enormously by audience — a technical B2B audience blocks far more than a general consumer one — but it is never zero, and it has been growing for years.
They attribute over different windows. Analytics assigns credit using a lookback window measured in days. A B2B sale takes months. Someone who found you in March and bought in July is, to analytics, a direct visit in July with no history. The CRM, if anyone asked at the point of enquiry, may say something completely different.
One counts sessions, the other counts people. A prospect who visits on their phone, then their laptop, then from the office is plausibly three users in analytics and one person in the CRM.
Between them, these four routinely account for a gap of tens of percent. A stable gap is not a bug. It is only a problem when it changes.
The part that is broken
Everything below is an implementation error and can be fixed.
Double-counted events. The commonest single fault. A conversion fires both on submit and on the thank-you page, or the tag is installed twice — once directly and once through a tag manager. The signature is an analytics number close to a round multiple of the CRM number.
Thank-you page counting. If the conversion is measured by arrivals at a confirmation page, then refreshes, bookmarks and people navigating back all count again.
Bot and internal traffic. Automated form fills, uptime monitors, and your own team testing the form. Some are filtered by default; plenty are not. Internal traffic is usually the larger share and the easiest to exclude.
Test submissions in production. Every developer who checks the form after a deploy adds one.
Events firing on the wrong pages. A conversion tag installed sitewide rather than on the confirmation step counts every page view as a conversion. This one is obvious in retrospect and produces spectacular numbers.
Spam. Bot form fills reach the CRM too, but they are frequently deleted there and never removed from analytics.
How to tell which you have
Take one month and reconcile it by hand. It takes a few hours and it settles the argument permanently.
- Export both lists for the same period, using the same time zone. Mismatched time zones alone can move the count by a percent or two.
- Match them on email address where you have it.
- Sort what is left into three piles: in analytics only, in the CRM only, in both.
- Look at twenty from each of the first two piles and write down why each one is there.
That last step is the whole exercise. Twenty examples will tell you the shape of your gap faster than any amount of dashboard comparison. You are looking for whether the "analytics only" pile is mostly duplicates and tests — fixable — or the "CRM only" pile is mostly consent and cross-device — structural.
Then write down the explained gap as a percentage. That number becomes the thing you monitor. Steady is fine. Moving means something changed.
What to report instead
The reporting mistake underneath all of this is treating analytics as a system of record. It is not, and it was never meant to be.
A workable split:
- The CRM is the source of truth for outcomes. Leads, opportunities, revenue. It is the system with a human checking it, and it is the one finance will believe.
- Analytics is the source of truth for behaviour. Which pages get read, where people arrive from, where they abandon. The CRM cannot see any of that.
Report the CRM number to the board. Use analytics to work out why the CRM number is what it is. Once the two systems have distinct jobs, the fact that they disagree stops being a problem and starts being expected.
When it is worth more effort
Two situations justify going further, usually with server-side tracking so that data collection happens on infrastructure you control rather than in the visitor's browser:
- The gap is large enough to change decisions — you are cutting a channel that may be working
- You need the closed-loop revenue picture, so the platforms optimise towards deals rather than form fills
Both are real reasons. Neither is worth doing before the manual reconciliation above, because server-side tracking implemented on top of a misunderstanding just produces a more expensive version of the same disagreement.
Working out which side of that line you are on is where most of our analytics engagements begin.