← All posts

Why Google Ads conversions don't match GA4

By Ben Bowler

Why Google Ads conversions don't match GA4

Two tabs open. Google Ads says 47 conversions last week. GA4 says 31. Same account, same date range, same conversion action. Somebody is going to ask which one is right, and the answer is neither, because they are not measuring the same thing.

The numbers are not supposed to match. Google documents five reasons they differ, and the biggest is the date: Google Ads credits a conversion to the day of the click, while GA4 credits it to the day the conversion happened. A sale on Thursday from a Monday click is Monday’s in one tool and Thursday’s in the other. On top of that, both tools estimate conversions they can’t observe directly, they use different cookie lifetimes, they count repeat conversions differently, and Google Ads filters out activity its invalid-click systems reject. Reconciling them to zero is not a project you can finish.

What bites isn’t the gap itself. It’s that the gap moves, always in the same direction, and anything optimising on a daily loop gets fooled by it.

The five reasons Google names itself

You don’t have to infer any of this. Google’s own page on importing Analytics key events lists the causes directly.

Attribution date. “Google Ads reports conversions from the date and time of the click that led to the successful action, not from the date of the successful action itself.” Analytics does the opposite. For any business with a conversion lag longer than a few hours, this alone puts the two reports permanently out of step.

Counting method. Google Ads lets you count “every” conversion after an interaction or just “one”. If a customer buys twice from one click, that’s two conversions or one depending on a setting most accounts were configured with years ago and nobody has looked at since.

Modelled data. Imported conversion reports “may include modeled conversions as estimates in cases where Google can’t observe all conversions”.

Cookie lifetime. “Google Ads cookies expire 90 days after a customer’s click, while Analytics uses a cookie that lasts for up to 2 years.” Long consideration cycles land in one tool and not the other.

Invalid clicks. Conversions can be “filtered out when they’re imported into your Google Ads account because of our invalid clicks technology”. Analytics never saw the filter and counts them anyway.

Five different mechanisms, no overlap between them, all running at once. A 30% gap between the two tools is unremarkable. A 0% gap would be genuinely strange.

Recent data always looks worse than it turns out to be

This is the part with money attached, and Google states it plainly. Conversions “can be reported up to 90 days after the click, depending on the conversion window you’ve chosen”, and Google’s guidance on conversion lag notes that recent data can look weaker because pending conversions haven’t been recorded yet while the ad spend is already fully counted.

Read that as a bias rather than a caveat. Yesterday’s cost is final the moment it’s spent. Yesterday’s conversions are provisional and will only ever go up. So every report you run on a recent window shows complete spend against incomplete conversions, and the more recent the window, the worse the campaign looks.

If your conversion lag is a day, this is a rounding error. If your average click converts eleven days later, a seven-day report is describing a period that is nowhere near finished, and comparing it to the previous seven days compares an unfinished number to a settled one. The comparison will show a decline. It will show a decline next week too, and the week after, regardless of whether anything is actually getting worse.

Nothing settles for at least five days

Even the estimates take their time. Google says modelled conversions “can take up to 5 days to fully process and stabilize”, and that they only appear when Google is “highly confident that conversions actually occurred as a result of ad interactions”. Accounts without enough regular conversion volume get no modelled conversions at all, which is its own trap: a small account and a large one are not merely different in scale, they are being measured by different methods.

GA4 is slower still. Modelled key events are “only included when there is high confidence of quality”, and attributed conversion data for each channel “can still be updated for up to 12 days after the conversion is recorded”. Below the traffic threshold the modelling doesn’t run, and those conversions land in Direct instead. Half the “our direct traffic is huge” mysteries are this.

So the honest reporting window is not yesterday, and it isn’t last week either. It’s a period old enough that both tools have stopped revising it. For most accounts that’s something like two weeks back, not the last fourteen days.

What this does to an agent that checks every morning

Hand this measurement environment to an agent with a daily loop and you get a machine for over-correction.

The loop looks reasonable written down: read yesterday’s performance, compare it to the prior period, adjust where the numbers got worse. Run it against data that is structurally incomplete at the recent end and it will find a decline nearly every morning, because a decline is what the data shape produces. It will then act, lowering a target or pausing an ad group, on a number that was going to fill in by itself within a week.

Then it gets worse, because the correction can’t be evaluated either. The agent changes something on Tuesday and reads the result on Wednesday, out of the same unsettled window. Whatever it sees, it will attribute to its own change. Two weeks of that produces a campaign that has been adjusted a dozen times, a bidding strategy that never left the learning period, and a log of confident reasoning where every step was drawn from provisional data.

None of this requires the agent to be badly built. It follows from a sound loop pointed at numbers that aren’t finished.

How to compare the two without going mad

A few rules that hold up in practice.

Pick one system of record per question. Platform numbers for in-platform decisions, because that’s what the bidding actually optimises against. Analytics or your warehouse for what happened on site. Your finance data for what was really earned. Don’t average them, and don’t ask which is right.

Match the windows before you compare anything. Different attribution dates, different lookbacks and different cookie lifetimes mean a like-for-like comparison needs deliberate setup. Most reported discrepancies are two tools answering different questions in the same shaped table.

Judge on settled periods. Compare the fortnight ending two weeks ago to the fortnight before it. Slower, duller, and it describes something real.

Give the agent the lag, not just the numbers. If something is going to read google_stats and act, it needs to know the conversion window and the typical lag, and it needs to treat the recent end as incomplete. An agent that knows to discount the last seven days will make far fewer changes, which is the correct outcome.

Keep the record of what changed. When numbers revise upward for a fortnight and something has been adjusting them daily, “did our changes work” is unanswerable without a timestamped log of every change. That’s the same argument as keeping spend controls outside the prompt: the guardrail that matters is the one that doesn’t depend on the model’s judgement in the moment.

The gap between your two tabs isn’t a bug to fix. It’s two measurement systems, both documented, both partly estimated, answering questions that were never the same question. What deserves your attention is the direction the error points, and what your automation does with it before the numbers finish arriving.


An agent optimising daily against numbers that take two weeks to settle will make a lot of confident, wrong changes. FlyWheel gives your AI agent one MCP surface across Reddit, Google Ads, Meta, and X, with every tool call logged with args, status, latency and actor, and new campaigns shipped paused by default. Get started with FlyWheel.