# Why Your Attribution Numbers Don't Match: Fix Inputs, Not Models

Which attribution model is most accurate? None of them, in the abstract. Accuracy lives in your data, not your model. Fix capture, dedupe, and identity first.

- Canonical: https://mbuzz.co/articles/fix-inputs-before-attribution-models
- Published: 2026-07-23
- Author: Holly Mehakovic, mbuzz (https://mbuzz.co)

---

> **TL;DR:** No attribution model is accurate in the abstract. Accuracy is a property of a model applied to a dataset, not of the model itself. Three input problems set the ceiling: completeness (did you capture the touch), identity (did you stitch touches to one person), and dedupe (did you count each conversion once). On complete, deduplicated, identity-resolved data, last-touch is a correct and auditable instrument, and it beats a Shapley model run on dirty data. Model sophistication is the wrong first upgrade. Fix the inputs, then the model choice becomes a real decision instead of a coin flip on garbage. Note that no attribution model measures incrementality; for that you need geo-lift, holdout tests, or MMM.


## The question has a hidden assumption

"Which attribution model is the most accurate?" is the most common question a marketer asks once they stop trusting last-click. It sounds like a question with an answer. It isn't, at least not at the scale most companies operate.

Accuracy is a property of a model applied to a dataset, not a property of the model on its own. A Shapley-value allocation computed over a dataset that is missing a third of the conversions, splits one buyer into four identities, and double-counts a refunded order is not more accurate than last-touch. It is a more sophisticated arithmetic performed on wrong numbers.

The industry argues the model layer, MTA versus MMM versus Shapley versus Markov, because that is the layer vendors differentiate on and the layer that is intellectually fun to discuss. The binding constraint for a company spending 5,000 to 100,000 dollars a month sits one layer down, in three properties of the data itself.

<div class="not-prose my-8 flex flex-wrap items-stretch gap-2">
  <div class="flex-1 min-w-[150px] bg-indigo-50 border border-indigo-200 rounded-lg p-4">
    <div class="text-[10px] font-bold tracking-[0.15em] text-indigo-500 mb-1">INPUT 1</div>
    <div class="text-sm font-semibold text-slate-900">Completeness</div>
    <div class="text-xs text-slate-500 mt-1">Did you capture the touch at all?</div>
  </div>
  <div class="flex-1 min-w-[150px] bg-indigo-50 border border-indigo-200 rounded-lg p-4">
    <div class="text-[10px] font-bold tracking-[0.15em] text-indigo-500 mb-1">INPUT 2</div>
    <div class="text-sm font-semibold text-slate-900">Identity</div>
    <div class="text-xs text-slate-500 mt-1">Did you stitch the touches to one person?</div>
  </div>
  <div class="flex-1 min-w-[150px] bg-indigo-50 border border-indigo-200 rounded-lg p-4">
    <div class="text-[10px] font-bold tracking-[0.15em] text-indigo-500 mb-1">INPUT 3</div>
    <div class="text-sm font-semibold text-slate-900">Dedupe</div>
    <div class="text-xs text-slate-500 mt-1">Did you count each conversion exactly once?</div>
  </div>
</div>

Those three determine the ceiling on accuracy. The model only redistributes credit within whatever you captured. It cannot recover a touch that Safari's tracking prevention deleted, and it cannot un-count a conversion your pixel fired twice.

## Garbage in, garbage out is a formal principle

The idea that downstream sophistication cannot rescue defective input is not a marketing folk theory. It has a name in the data-quality literature. Kilkenny and Robinson formalize it in the *Health Information Management Journal* (2018): the validity of any output is bounded by the validity of its input, regardless of the processing method applied. Their domain is health records, but the principle is domain-general. A leading attribution model running on broken data is subject to exactly the same ceiling as a spreadsheet.

This reframes the whole model debate. Model choice decides how you slice the credit. Input quality decides whether the thing you are slicing bears any resemblance to what actually happened.

## Why your inputs are probably broken

Three well-documented mechanisms strip signal out of a client-side dataset before any model ever sees it.

**Tracking loss.** Client-side pixels leak roughly 30 to 40 percent of conversions to Safari's Intelligent Tracking Prevention, iOS App Tracking Transparency, and ad blockers. Multiple 2026 vendor benchmarks converge on this range, with server-side implementations recovering most of it. Treat the exact recovery percentages as directional, since these are vendor-published rather than independently audited, but the load-bearing claim is well established: a large fraction of touches never reach a client-side dataset.

**Ad blockers alone.** Ad blockers hide an estimated 15 to 30 percent of analytics traffic before attribution runs at all (Kissmetrics, 2026). That is a floor on the loss, independent of iOS and Safari.

**Identity fragmentation.** Under Safari's tracking prevention, first-party cookies are capped at 7 days, and as short as 24 hours for cookies set through link decoration (Blast Analytics analysis of ITP). When the cookie expires, GA4 treats a returning user as brand-new. Littledata's analysis of 812 ecommerce stores put attribution loss for the Safari mobile search slice alone at around 8 percent, a concrete lower bound for one channel and browser, not the headline number. The mechanism is what matters: cookie expiry deletes the connection between sessions, which is exactly the identity-resolution failure that breaks any multi-touch model.

Put these together and the picture is not a clean dataset with a bit of noise. It is a dataset where a third of the touches are gone and a large share of the multi-day journeys have been shredded into disconnected single-touch fragments.

## What this does to a "sophisticated" model

Here is the uncomfortable part. On complete, deduplicated, identity-resolved data, last-touch is a defensible measurement instrument, and it beats Shapley run on dirty data.

Last-touch has one job: attribute the conversion to the last observed channel. On clean data it does that job correctly and auditably every time. Shapley's advantage is that it redistributes credit across the whole journey, but that advantage is only real if the journey is fully observed. When 30 to 40 percent of the journey is missing, Shapley is not allocating credit across the real journey. It is allocating credit across the fragments that survived tracking loss, then dressing the result in four fairness axioms.

Those axioms, efficiency, symmetry, the dummy property, and additivity, are real mathematical guarantees about how credit is split given the coalition data. They say nothing about whether the coalition data is complete. This is worth sitting with. The flagship "Shapley done right" system in the academic literature, the causally-driven incremental MTA model of Du, Zhong, Nair, Cui and Shou (arXiv 1902.00215, 2019), allocates Shapley credit only after a recurrent neural network estimates incremental purchase probability, and it is trained on roughly 300 million users, 160,000 brands, and 80 billion impressions. That is the opposite of a small team bolting a Shapley library onto a leaky pixel export.

<div class="not-prose my-8 bg-white border border-slate-200 rounded-lg overflow-hidden">
  <div class="px-5 py-3 border-b border-slate-200 bg-slate-50">
    <p class="text-xs font-bold text-slate-500 tracking-[0.15em]">SAME MODEL, TWO DATASETS</p>
  </div>
  <div class="px-5 py-5 space-y-3">
    <p class="text-sm text-slate-700"><strong class="text-slate-900">Question:</strong> is Shapley more accurate than last-touch?</p>
    <p class="text-sm text-slate-700">It depends entirely on the data underneath it, not the math on top of it.</p>
    <div class="grid grid-cols-2 gap-3 mt-4">
      <div class="bg-emerald-50 border border-emerald-200 rounded-md p-3">
        <div class="text-[10px] font-bold tracking-[0.15em] text-emerald-700 mb-1">ON CLEAN DATA</div>
        <ul class="text-sm text-slate-700 space-y-1">
          <li>Last-touch: correct, auditable, one known bias</li>
          <li>Shapley: adds real journey information</li>
          <li class="pt-1 border-t border-emerald-200 mt-2 text-emerald-700"><strong>The model debate is worth having</strong></li>
        </ul>
      </div>
      <div class="bg-amber-50 border border-amber-200 rounded-md p-3">
        <div class="text-[10px] font-bold tracking-[0.15em] text-amber-700 mb-1">ON DIRTY DATA</div>
        <div class="text-3xl font-bold text-amber-700 mb-2">~⅓ gone</div>
        <div class="text-xs text-amber-700">Shapley allocates across surviving fragments and hides the loss behind fairness axioms. Last-touch is at least wrong in a way you can see.</div>
      </div>
    </div>
  </div>
</div>

## Three ways this goes wrong in practice

The failures are not hypothetical. Each of these is a specific input defect that a model amplifies rather than corrects.

<div class="bg-slate-50 border-l-4 border-slate-400 p-5 my-8 rounded-r-md not-prose">
  <p class="text-xs font-bold text-slate-500 tracking-[0.15em] mb-3">WORKED EXAMPLE A: THE DEDUPE BUG DRESSED AS A MODEL INSIGHT</p>
  <p class="text-sm text-slate-700 leading-relaxed mb-3">A B2B SaaS company, about 40,000 dollars a month in spend and 250 conversions a month. Their CRM fires a conversion on both "trial started" and "trial started (webhook retry)," so roughly 18 percent of conversions are double-counted. The duplicates cluster on the paid-search touch that immediately precedes both events.</p>
  <p class="text-sm text-slate-700 leading-relaxed mb-3">Their new Shapley model sees inflated conversion counts concentrated on paid search and upweights it by about 15 percent. True paid-search credit was around 30 percent; the report now says 45 percent. The team cuts LinkedIn budget to feed paid search. Paid search never actually moved. A dedupe bug moved it.</p>
  <p class="text-sm text-slate-700 leading-relaxed">Last-touch on the deduplicated data would have shown paid search flat. The sophisticated model amplified the input error; the simple model on clean data would not have.</p>
</div>

<div class="bg-slate-50 border-l-4 border-slate-400 p-5 my-8 rounded-r-md not-prose">
  <p class="text-xs font-bold text-slate-500 tracking-[0.15em] mb-3">WORKED EXAMPLE B: THE IDENTITY SPLIT THAT BREAKS BOTH MODELS</p>
  <p class="text-sm text-slate-700 leading-relaxed mb-3">An ecommerce brand, about 25,000 dollars a month, with a Safari-heavy audience at roughly 55 percent of sessions. Tracking prevention resets the first-party cookie inside 24 hours. A buyer who sees a paid-social ad on Monday and converts through email on Thursday is recorded as two separate identities.</p>
  <p class="text-sm text-slate-700 leading-relaxed mb-3">Last-touch credits email 100 percent, correct for the fragment it can see, blind to the paid-social origin. The new Shapley model cannot see the link either, so it allocates across the surviving non-Safari journeys and generalizes. Both models are computing on a dataset where a majority of cross-day journeys have collapsed into single-touch fragments.</p>
  <p class="text-sm text-slate-700 leading-relaxed">The fix that changes the answer is server-side identity stitching keyed on a durable ID, such as a hashed email captured at both touches, not swapping the allocation math. Once the journeys are stitched, last-touch and Shapley finally disagree about something real, and only then is the model debate worth the meeting.</p>
</div>

<div class="bg-slate-50 border-l-4 border-slate-400 p-5 my-8 rounded-r-md not-prose">
  <p class="text-xs font-bold text-slate-500 tracking-[0.15em] mb-3">WORKED EXAMPLE C: BELOW THE FLOOR, THE MODEL IS MODELING STRANGERS</p>
  <p class="text-sm text-slate-700 leading-relaxed mb-3">A Series-A marketplace, about 8,000 dollars a month and 120 conversions a month, below the roughly 300-conversions-per-30-days zone where data-driven attribution is stable. They enable it because it is the accurate-sounding default. At their volume the model leans on Google's cross-account priors, so their reported channel mix partly reflects aggregate advertiser patterns rather than their own funnel.</p>
  <p class="text-sm text-slate-700 leading-relaxed">Meanwhile their client-side pixel is missing 30 to 35 percent of conversions to ad blockers and tracking prevention. The net result is a model trained partly on other companies, run on two-thirds of their own data. Last-touch on server-side-complete data would at least be their data, counted once, attributed by a rule they can audit. The upgrade with the highest accuracy per dollar here is server-side capture, not a fancier model.</p>
</div>

## Google already conceded this

The platform that popularized rules-based multi-touch has quietly moved to the same conclusion. Google Ads no longer supports first-click, linear, time-decay, or position-based attribution. Two models remain: Last Click and Data-Driven (Google Ads Help, "About attribution models," 2026). The middle tier of models that were smarter than last-click but still rule-based was not worth maintaining, and the debate collapsed to two poles.

Which pole wins is decided by data, not by model theory. Data-driven attribution has a volume floor. Google historically required 3,000 ad interactions and 300 conversions in 30 days to qualify, and 2,000 interactions with 200 conversions to maintain it (Google Ads Help, "About Switch to DDA"). Google has since relaxed the hard gate, but below roughly 300 conversions a month the credit allocation is explicitly lower-confidence and noisy, leaning on aggregate cross-account patterns rather than your own behavior. At 5,000 to 100,000 dollars a month, many buyers sit near or below that floor while simultaneously losing a third of their captured data. Both failure modes point at inputs, not model choice.

## How to check your own inputs

You do not need a research team to find out whether your data can support a model debate. You need three ratios. A rough version of the first one looks like this against your own warehouse.

```sql
-- Capture gap: server-side vs client-side conversion counts
SELECT
  date_trunc('week', conversion_at) AS week,
  count(*) FILTER (WHERE source = 'server') AS server_side,
  count(*) FILTER (WHERE source = 'client') AS client_side,
  round(
    100.0 * (count(*) FILTER (WHERE source = 'server')
      - count(*) FILTER (WHERE source = 'client'))
    / nullif(count(*) FILTER (WHERE source = 'server'), 0)
  , 1) AS pct_missed_client_side
FROM conversion_events
GROUP BY 1
ORDER BY 1 DESC;
```

The three numbers to hold up against each other:

| Input | What to measure | A problem looks like |
|---|---|---|
| **Capture** | Server-side conversion count vs client-side pixel count | A large gap means you are losing touches before any model runs |
| **Dedupe** | Attributed conversions vs unique fulfilled orders or signups in your system of record | A gap means you are double-counting, and the model will amplify it |
| **Identity** | Share of Safari and mobile sessions, and your cross-day match rate | High Safari share plus a low match rate means journeys are fragmented |

If any of these is off, you have an input problem, and no model swap fixes an input problem. It only relabels it.

## The honest boundary: none of this is causal

Say this early and often, because a measurement-literate reader will stop trusting the whole argument if it is fudged. Neither last-touch nor Shapley measures incrementality. Both answer "which touchpoints does the observed data associate with conversions," not "which touchpoints caused conversions that would not otherwise have happened." Fixing your inputs makes your attribution correct as a description of observed behavior. It does not make attribution causal.

Two more limits belong in plain sight:

Last-touch keeps one structural bias even on perfect data. It systematically starves top-of-funnel. On complete data it will still under-credit awareness channels like display and early paid social, and over-credit closing channels like brand search, email, and retargeting. Clean inputs do not fix that. The honest claim is not that clean-data last-touch is the best model. It is that clean-data last-touch is a correct, auditable instrument whose one bias is known and points in a fixed direction, which is more useful than a multi-touch model whose errors are unknown and input-driven. Known bias beats unknown noise.

Fixing inputs is not free either. Server-side tracking, identity stitching, and dedupe are engineering work with their own failure modes: consent compliance, hashing and matching errors, server-event dedupe logic, and the false-merge risk that comes with identity resolution. The claim is that this work buys more accuracy per dollar than a model swap at this spend level, not that it is costless. "Clean" is a direction, not a finished state.

For causality, you need experiments. Geo-lift and holdout tests measure what a channel actually causes; MMM estimates portfolio contribution including offline. Clean attribution is the reliable descriptive layer that makes those causal tests interpretable. It is the floor, not the ceiling. This is also where the point about model comparison earns its keep: when you can see the same clean data through several models at once, the spread between them is information. If last-touch says a channel is 15 percent of credit and Markov says 40 percent, the real answer lives in the fight between the models, and that fight is only worth watching once the data underneath both is complete.

## The sequencing, stated plainly

Model sophistication is the wrong first upgrade. The first upgrade is the input layer. This is about the order of operations, not a ban on multi-touch models. When your data genuinely is complete and your journeys are long and multi-channel and high-volume, a data-driven or Shapley model adds real information that last-touch discards, and it is worth adopting.

But you have to earn that debate. Buy the model argument only after your inputs can support it. Until then, the most accurate thing you can do is count your conversions once, capture them server-side, stitch them to real people, and attribute them with a rule you can read.

## Key takeaways

- Accuracy is a property of a model applied to a dataset, not of the model itself
- Three inputs set the ceiling: completeness, identity resolution, and deduplication
- On clean data, last-touch is correct and auditable and beats Shapley on dirty data
- Client-side tracking loses roughly a third of conversions to ITP, ATT, and ad blockers
- No attribution model measures incrementality; clean inputs make it correct, not causal


## FAQ

**Which attribution model is the most accurate?**

None, in the abstract. Accuracy lives in the data, not the model. On complete, deduplicated, identity-resolved data, last-touch is correct and auditable, and data-driven adds real information when journeys are long and conversion volume is high. On dirty data, every model is wrong, and the sophisticated ones just hide it better. Fix your inputs first, then the model choice becomes a real decision.

**We already have last-touch and it feels wrong. Should we move to data-driven or Shapley?**

First prove your inputs are clean: your server-side capture rate, your dedupe rate, and your cross-day identity match rate. If any of those is broken, a model swap will change your numbers but not their correctness, and you will not know whether the change was signal or an amplified input bug. Fix the inputs, keep last-touch, and see if it still feels wrong. Often it stops.

**Isn't last-touch just obviously bad? Google made data-driven the default.**

Google also deleted first-click, linear, time-decay, and position-based, and data-driven historically needed about 300 conversions in 30 days to be stable. Below that it leans on Google's cross-account patterns rather than your own funnel. Many companies spending 5,000 to 100,000 dollars a month sit near or below that floor while also losing 30 to 40 percent of conversions client-side. Last-touch on complete server-side data is at least your data, counted once, attributed by a rule you can audit.

**How do I know my data is actually dirty? What do I measure?**

Three numbers. Capture: compare your server-side conversion count against your client-side pixel count, a large gap means you are losing touches. Dedupe: compare conversions against unique fulfilled orders or signups in your system of record, a gap means double-counting. Identity: look at your share of Safari and mobile sessions and your cross-day match rate, high Safari share plus a low match rate means fragmented journeys. If any of these is off, you have an input problem, not a model problem.

**If we clean the data, does last-touch finally tell us what drives growth?**

No, and this is the honest boundary. Clean-data last-touch tells you correctly which channel the buyer touched last. It still under-credits top-of-funnel channels and it still is not causal. For what actually drives incremental growth you need experiments: geo-lift, holdout tests, or MMM for the portfolio. Clean attribution is the reliable descriptive layer that makes those causal tests interpretable. It is the floor, not the ceiling.

**Doesn't a model like Shapley or data-driven handle noisy data better because it learns patterns?**

It is robust to random noise, not to systematic input defects. ITP-driven journey fragmentation, double-counted webhook conversions, and identity splits are all systematic and correlated with channel. A model launders that systematic error into a confident-looking allocation, which is worse than an auditable simple rule because the error becomes invisible.


