Adstock: the assumption that last week's spend is still selling this week
In short
Adstock is the transformation that carries part of this week's media spend into the following weeks before a mix model ever sees it. The decay rate is a prior you impose: on the same 3-week flight, a 1-week half-life leaves 26% of the transformed weight after the flight ends and a 4-week half-life leaves 50%. Unless spend starts and stops sharply, the data cannot tell you which is right.
Key takeaways
- Adstock transforms the input before fitting, so it changes the answer whatever the model does afterwards.
- Under steady always-on spend the retention rate and the coefficient trade off exactly, so neither is identified.
- A longer half-life hands post-flight sales to the channel with the longer memory, arithmetically and unavoidably.
- Report contributions across a half-life range, not at a point, and say which range you used.
Adstock is the transformation applied to a media series before a mix model is fitted: this week's model input is this week's spend plus a share of last week's input. That share is the retention rate, usually quoted as a half-life. It encodes a belief you impose rather than a fact the data hands you.
The transformation happens before any modelling decision anyone normally argues about. Choose a 1-week half-life and a channel's effect has nearly gone a fortnight later; choose 4 weeks and half its transformed weight sits after the campaign ended. Same spend, same sales, different answer.
What the transformation does to a spend series
Geometric adstock is 1 line: this week's adstocked value is this week's spend plus the retention rate times last week's. Retention rate and half-life are the same parameter in 2 units — 1 week is 0.50, 2 weeks roughly 0.71, 4 weeks roughly 0.84. Below, a 3-week flight of 100 a week, transformed 3 ways.
| Week | Spend | Half-life 1 week | Half-life 2 weeks | Half-life 4 weeks |
|---|---|---|---|---|
| 1 | 100 | 100 | 100 | 100 |
| 2 | 100 | 150 | 171 | 184 |
| 3 | 100 | 175 | 221 | 255 |
| 4 | 0 | 88 | 156 | 214 |
| 5 | 0 | 44 | 110 | 180 |
| 6 | 0 | 22 | 78 | 151 |
| Share landing after the flight | 0% | 26% | 41% | 50% |
Two properties fall out of that arithmetic. Total transformed volume is raw spend divided by 1 minus the retention rate, so the 4-week version carries roughly 6 times the raw total and the 1-week version twice it. And in week 6 the long-memory series carries 151 units against 22 — nearly 7 times more media pressure available to explain any late sales.
Why the data usually cannot tell you the half-life
Fit a channel that ran at a steady level all year and the adstocked series is a near-constant multiple of the raw one. The model sees the same shape at every candidate half-life, and only the product of the coefficient and the long-run multiplier is pinned down: halve the coefficient, lengthen the memory to compensate, and the fitted contribution is identical.
What identifies a decay rate is variation the decay can explain: abrupt starts, hard stops, dark weeks, bursts of very different weight. A flighted television plan carries that information; a search budget held within a few percent of the same number every week carries almost none. It is the same identification problem behind a channel handed a negative coefficient.
What the choice does to the number a client sees
The damage is rarely in the total. It is in the split between channels and the timing of credit. Give brand media a 4-week memory and search a 1-week memory, and every sale in the fortnight after a burst has far more transformed brand pressure available to explain it. Reverse the priors and those weeks read as search converting demand that was already there.
That is a budget decision made by a parameter nobody chose deliberately. It is also why mix modelling and touch attribution disagree so often — different questions, different memories, as separated in mix modelling, touch attribution and experiments. Adstock is memory inside the model; a lookback window is memory inside the counting rule that produced the outcome column, which is the lookback window.
A half-life is a budget decision wearing the clothes of a preprocessing step, and it is usually made by whoever wrote the default in the script.
Choosing a half-life you can defend in the meeting
- Set a candidate range per channel from the mechanism, not from a table. A channel intercepting existing intent decays in days; a channel building memory for a considered purchase plausibly decays over weeks.
- Check whether the spend history can identify anything. Plot weekly spend per channel; if it never stops and never spikes, declare the half-life assumed rather than estimated, in writing.
- Sweep the range and report the spread. Fit at each candidate, record the contribution each produces, and carry the minimum and maximum into the readout instead of the best fit alone.
- Pin it with an experiment where the money justifies it. A geo holdout measures the post-flight tail directly and its interval bounds the plausible half-lives, provided it was powered — the failure examined in the test that came back saying nothing.
- Freeze the assumption for the reporting year and log every change. A half-life edited between quarters silently restates history, and the restatement reads as a performance change.
Two mechanics deserve a sentence each. Delayed adstock, where the peak lands a week or 2 after the spend, fits media people notice and act on later; it adds a parameter you also cannot identify from a flat spend series. Saturation — the curve making the tenth unit worth less than the first — is a separate transformation applied in a documented order, not an alternative to adstock.
Teams fitting these models repeatedly end up with a small internal tool that stores the assumption set beside every result, which is why we treat it as a product build rather than a spreadsheet. An agency doing it across clients also has to keep those weekly tables in one warehouse without any client's data meeting another's, worked through in one warehouse, many clients who never overlap. Both sit inside the attribution, incrementality and mix work we do for marketing and advertising teams.
Frequently asked questions
Short answers to the follow-ups this page tends to raise.
How do I choose an adstock half-life for a channel?
Start from the mechanism, then bound it with whatever evidence you have. Channels that intercept demand somebody already has decay fast, often within days; channels building familiarity for a considered purchase plausibly persist for weeks. Sweep a range rather than picking a number, report the contribution spread it produces, and narrow it with an incrementality test when the budget at stake justifies one.
Can adstock be estimated from the data rather than assumed?
Only when the spend history varies enough to identify it. If a channel ran at a steady level all year, the adstocked series is a near-constant multiple of the raw one, and the coefficient and retention rate trade off exactly, so many combinations fit equally well. Abrupt starts, dark weeks and heavy bursts are what make the decay estimable.
What is the difference between adstock and an attribution lookback window?
Adstock is memory inside the model; a lookback window is memory inside the counting rule that produced the data. Adstock decides how much of last week's spend still counts as pressure this week, while the window decides which conversions are counted against an ad at all. They can point in opposite directions, and changing either one moves the reported numbers with nothing changing in the market.
- mix modelling
- adstock
- measurement
- media
The work behind this page
Builds from our portfolio that this page draws on.
Read next
- The model hands a channel a negative coefficient nobody believesAn implausible coefficient is usually a statement about your spend history, not about the channel. Five causes, the checks that separate them, and where each branch ends.diagnostic
- The lookback window: the assumption inside every conversion figureA lookback window has two dimensions set independently, so two platforms reporting different totals for the same sales are not disagreeing. They are counting different event classes.definition
- The test finished and the confidence interval still straddles zeroAn interval containing zero can mean the channel does nothing, or that the test was never able to see an effect this size. One calculation separates them before anyone moves budget.diagnostic
- A slice of events lands before the visitor has answered the bannerEvents arriving with an absent consent field are not a compliance abstraction. They are a race between two scripts, and the race has a rate you can measure this afternoon.diagnostic
- Click identifiers: the URL parameters that let a server-sent conversion find the ad that caused itA campaign tag describes where traffic came from. A click identifier is the key that joins a sale back to a specific click — and only one of the two is load-bearing.definition
- Consent state: a typed field on each event, not a switch on the pageThe pageview before the banner answer and the purchase after it are both correct, and they carry different consent values. That only works if consent travels per event.definition
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