Marketing, Advertising & AdTech// diagnostic

The ad account reports a third more conversions than the warehouse, every single month

In short

A persistent platform-versus-warehouse gap has 4 causes: the numbers are dated differently, part of the platform figure is modelled rather than observed, one conversion is being counted twice, and the 2 sides measure different windows. Duplication and window length are defects you can close. Date basis and modelling are definitional, so the honest outcome is a documented tolerance.

Key takeaways

  • Rank before you investigate: date basis and modelling explain most of a stable gap, duplication and window length explain most of a sudden one.
  • Only 2 of the 4 causes are defects. Deduplication and window length are closable; date basis and modelled conversions are definitional.
  • The confirming check is one day, one campaign, bucketed by date basis, transport and consent state — not a month-level total.
  • A stable gap that moves less than 5 points month to month is a tolerance to document. One that swings 15 points is a defect to chase.
  • Write the tolerance into the report itself, with the date basis stated, or the same argument returns every month.

Four things produce a persistent gap between an ad account and a warehouse, and they are worth ranking before anyone opens a query editor. The 2 numbers are dated differently. Part of the platform's figure is modelled rather than counted. The platform is counting a single conversion twice. The 2 sides are measuring windows of different length. Deduplication and window length are engineering defects with fixes. Date basis and modelling are definitional differences between 2 systems that were never built to agree, and the correct response to them is a documented tolerance.

Say the last part out loud early, because the expensive version of this problem is not the gap. It is the meeting: a monthly hour in which a performance team and a data team re-derive the same 4 explanations from scratch, and nobody writes anything down. An exact match is not an available outcome. A stable, explained, bounded difference is.

Confirm the shape of the gap before anyone explains it

Month totals cannot be diagnosed, because every cause is present in them at once. Take one day and one campaign, and cut both sides the same way. An afternoon spent here removes at least 2 of the 4 candidates.

  1. Pick a single completed day at least 10 days in the past, so the platform's own figures have finished settling, and a single campaign with enough volume to be readable — 50 conversions is a workable floor.
  2. Pull the platform's number twice: once dated by conversion date, once dated by the date of the click that got credit. Most interfaces offer both. The difference between those 2 pulls is the size of your date-basis problem, measured rather than argued.
  3. Pull the warehouse number for the same day from the raw export, not from a dashboard, and confirm the day's partition is complete — provisional data is its own class of confusion, covered in yesterday's numbers moving after the table lands.
  4. Bucket the warehouse rows 3 ways: by transport (browser only, server only, both), by consent state at the time of the event, and by whether a click identifier was present. Three counts, one query.
  5. Compare the both-transports count against the platform's figure. If the platform number exceeds the sum of your distinct conversions, you have duplication. If it exceeds your rows carrying a click identifier but not your total, you are looking at modelling and matching loss.
  6. Write the 5 numbers into a table and keep it. The next time this argument starts, it starts from evidence.

The four causes, ranked

CauseEffect on the gapConfirming checkClosable?
Date basis — click date versus conversion datePlatform higher in recent periods, converging as older days fill inPull the platform figure on both bases for one day; the delta is the answerNo. Restate the report instead
Modelled conversionsPlatform higher by a share that grows as consent and identifier coverage fallPlatform interfaces separate observed from modelled; if yours does not, the gap will not close below the modelled shareNo. Document it
Duplication across transportsPlatform higher by close to a whole multiple, and it appears on a rollout datePlatform total exceeds the count of distinct order identifiers on your sideYes. A pipeline defect
Window lengthPlatform higher when its lookback is longer than the join your warehouse query usesRe-run the warehouse query on the platform's configured window; the gap should moveYes. Align the query, or the setting
What each cause does to the gap, and whether engineering can close it

Rank matters because the investigation order is the opposite of the intuitive one. A stable gap that has been the same size for 6 months is almost never duplication — duplication arrives on a date. A gap that changed shape last Tuesday is almost never date basis, because date basis does not change unless someone changed a report.

The two you can close: duplication and window length

Duplication is the only cause that makes the platform figure wrong rather than different. It appears as a step change on the day server-side sending was enabled, with order volume flat underneath it, and it is isolated to one of a small number of failure points in conversions counting twice after the server goes live. Rule it out before touching anything else, because every other explanation is contaminated while it is present.

Window length is duller and more common. The platform is configured with a click-to-conversion lookback; your warehouse query joins conversions to clicks with whatever window someone typed 2 years ago, and the 2 have never been compared. Read the configured value from the account, put it in the model as a named parameter rather than a literal, and note it in the report header. If the model itself is ad hoc, this is a good moment to build it properly — the layering is in turning raw event rows into a model people can query.

The two you can only account for: date basis and modelling

Date basis is the largest cause of a stable gap and the least interesting once understood. Ad platforms credit a conversion to the day of the click that earned it, because that is the day the money was spent. A warehouse records the day the order was placed. For a business with a same-day purchase cycle these nearly agree; for one with a 3-week consideration window they never will, and the gap is largest in the most recent 2 weeks — exactly the period people look at. Restating the warehouse query on click date is legitimate and takes an hour. What is not legitimate is comparing a click-dated number to a conversion-dated one and calling the difference a data quality problem.

Modelling is the harder conversation. Where a conversion cannot be observed — no identifier, no consent for storage, a browser that dropped the join — platforms estimate how many occurred and report the estimate alongside the observed count. No row exists underneath that figure, which is why it cannot be exported, joined or matched; the mechanism is set out in why modelled conversions never reconcile to rows. The practical consequence is a floor: your gap will not close below the modelled share, however good your pipeline gets.

Two systems that were built to answer different questions will not agree by being asked harder. The deliverable is not a match. It is a difference small enough, stable enough and explained well enough that nobody has to re-derive it next month.

What a tolerable gap looks like, and how to write it down

There is no industry constant here, and anyone quoting one is quoting a number from a different business. What is transferable is the shape of the judgement. We treat stability as the signal rather than size: a gap that sits within a 5-point band for 3 consecutive months is a definitional difference, and one that swings 15 points between months is a defect regardless of its average. Size only matters relative to how much of the platform figure is modelled and how long the consideration window is.

  • State the date basis on every report, in the header, in words. Most of these arguments are 2 people comparing correctly-computed numbers that were never comparable.
  • Publish the observed and modelled split where the platform exposes it, so the irreducible part of the gap is visible rather than argued about.
  • Track the gap as a monitored series with an alert on the change, not the level. A jump is a defect; a level is a definition.
  • Automate the monthly reconciliation. It is a scheduled query, a variance check and a written explanation — bounded, repeatable work of the kind we describe in AI agents and automation, with a person still reading the output.
  • Recheck the tolerance whenever an attribution setting changes, since the band is only valid for the configuration it was measured under — the discipline in changing attribution models mid-year.

Where the tree ends: fix, restate, or document

  1. Fix. The platform figure exceeds your distinct order count, or the gap appeared on a datable event. This is duplication or a misconfigured window, and it is a pipeline change with a testable outcome.
  2. Restate. The gap tracks the difference between click date and conversion date, and shrinks as older days fill in. Re-cut the warehouse query on click date, publish both, and stop comparing the wrong pair.
  3. Document. What remains after the first 2 is modelling plus matching loss. Write the tolerance into the report as a stated band with the date it was measured, and review it quarterly rather than monthly.

The seller side of advertising has the same structural lesson, in a different costume: when a buyer's records disagree with yours about what you are entitled to sell, the fix is not counting harder but correcting a declared record both parties read, which is what sits behind buyers flagging our inventory as unauthorised. Reconciliation work is nearly always about agreeing a definition, then encoding it, then leaving it alone.

If this work is going outside — and it often should, because it is unglamorous and specific — the questions worth asking are the ones in choosing a development partner. The rest of the decisions around the pipeline sit under tracking, consent and event pipelines, part of our marketing and advertising practice.

Frequently asked questions

Short answers to the follow-ups this page tends to raise.

What is an acceptable discrepancy between ad platform and warehouse conversions?

Stability matters more than size: a gap that stays within a 5-point band across 3 months is a definitional difference, while one swinging 15 points between months is a defect whatever its average. There is no universal percentage, because the honest floor depends on how much of the platform figure is modelled and how long your consideration window is. Measure your own band, write it into the report, and alert on changes rather than on the level.

Can conversion numbers ever be made to match exactly?

No, and promising it is how these projects fail. Two of the 4 causes are definitional — the platform dates a conversion to the click that earned it, and part of its figure is modelled with no rows underneath it. Both survive any amount of engineering. What is achievable is closing the 2 defects, restating the report on a comparable date basis, and documenting the remainder as a measured tolerance.

Why does the ad platform report more conversions than the warehouse rather than fewer?

Because 3 of the 4 causes push the same direction. Click-date crediting front-loads conversions into recent days, modelling adds an estimate for conversions that could not be observed, and duplication adds a second copy of events already counted. Only window mismatch can push either way. A platform figure lower than the warehouse usually means something different: conversions the platform never received at all, which is a delivery problem rather than a reconciliation one.

Should the reconciliation run on the raw export or on a modelled table?

Run the diagnostic on the raw export and the routine reconciliation on the model. The export is the only place where a row is a row, so it is the right surface for finding a duplicate or a missing identifier. Once the causes are understood, the recurring monthly check belongs in the modelled layer with the window and date basis as named parameters, so a change to either is visible in a diff.

  • reconciliation
  • attribution
  • conversion tracking
  • reporting
// shipped work

The work behind this page

Builds from our portfolio that this page draws on.

Read next

Working on something in this space?

Tell us where you are in a sentence or two. We'll tell you honestly whether we're the right team, and what a sensible first slice of the work looks like.

Start the conversation