Every few weeks someone sends me a screenshot of two reports and asks which one is right. The ad server says 200 conversions, the DSP says 140, the client's analytics says 90. All three are right. They are counting different things, and the gap is only a problem when nobody can explain it.

This is what I check, in order, when the numbers disagree. Most gaps come from the first three.

1. They are not counting the same event

A DSP counts conversions it can attribute to an impression or click it served. An ad server counts conversions its own tag saw, across every platform that pointed at it. Analytics counts sessions and goals, usually last click, with no view-through at all. Three definitions, three numbers.

The most common version of this: a client runs YouTube through Google Ads and display through DV360, and someone adds the two together. Google Ads conversions and CM360 Floodlight conversions are counted by different systems with different windows. The total means nothing. The rule I use now on every account: if every pound in a table is Google Ads YouTube, report the in-platform Google Ads conversions. If a table mixes DV360 and YouTube, report from CM360 Floodlights for both, so both sides are counted the same way. Write the source on the report. It ends the argument before it starts.

2. View-through versus click-through

Display and video conversions are mostly post-impression. On one gambling account I looked at, the deposit conversion had zero post-click conversions in 30 days and everything was post-view, while registrations did get post-click. Same site, same tags, different user paths. If your analytics tool is last-click only, it will never see most of what display drove, and no amount of tag fixing will change that. That is a reporting choice, not a fault.

3. The tag does not fire where you think it does

Before you compare numbers, prove what fires. I have seen a channel report as "display" for months because the trackers were created under the display site in Campaign Manager, even though the ads had been moved into video campaigns. CM360 attributes the channel by which site the placement sits under, not by what the ad actually is. Nobody had touched the tags, so nobody suspected them.

Consent is the other silent one. A consent banner that blocks the ad server tag until the user accepts will cut your ad server conversions by whatever your accept rate is, while the platform's own modelled numbers carry on. The gap looks like a tracking bug. It is a consent setting.

4. Server-side tracking loses identity

Server-to-server postbacks fix a lot of browser problems and create a new one: the server often has no idea who the user is. On one account, 47% of first-deposit postbacks arrived with no cookie ID at all, because the event fired from the payment backend, which has no browser to read. Those conversions can never be attributed to an ad, however good the media was. Further down the funnel it got worse: 13% no-cookie on registration, 47% on first deposit, 72% on repeat deposits.

There was a second, nastier problem underneath. The DSP's server-side endpoint only accepted cookie IDs up to 19 digits. Around 22% of genuine users had 20-digit IDs. Their conversions were sent, accepted with a 200 OK, and silently never matched. A 200 OK is not proof the platform kept the event.

5. Windows, time zones and duplicates

Attribution windows differ by default across platforms (7, 14, 28, 30 days, view versus click). Time zones move conversions across a day boundary. Duplicate firing inflates one side: on the account above, about 6% of deposit events and 17% of registration events were the same cookie firing again the same day with no transaction ID to dedupe on. Each of these is small. Together they are the "unexplained" 10 to 15%.

What a normal gap looks like

  • Clicks: ad server versus DSP within a few percent. Bigger than that and something is wrong with the click tag or a redirect.
  • Impressions: DSP versus ad server within about 5%. Discrepancies above 10% usually mean a tag firing before render, or bot filtering on one side only.
  • Conversions: ad server versus analytics can differ by half or more once view-through is involved. That is not a fault. It needs a written explanation once, then it stops being a question.

The process that stops the arguments

  1. Pick one source of truth per table and write it on the report.
  2. Audit what actually fires: every tag, pixel and Floodlight, on which pages, with what consent state. Do this with a real test conversion, not by reading the tag manager.
  3. Reconcile once, properly, and document the known gap and its causes.
  4. Alert on drift. If the ad server to DSP click gap moves from 3% to 15%, something changed. Catch it that week, not at the quarterly review.

One more thing about how we run this. Every cause on this list lives in a memory file our agents read before they touch a client's tracking: the consent gap, the 19-digit ID cap, the trackers under the wrong site. The audit is run by a Claude agent working through the tag manager, the ad server and the platform APIs, and it checks the list so a human does not have to remember it. That is why the same fault does not get rediscovered on the next account.