Adstock and Carryover Effects in MMM: Why Marketing Has a Memory

By Kiran Akkineni · · 11 min read

If you ran a TV ad on Monday and measured sales on Monday only, you'd conclude TV doesn't work. Most of the people who saw the ad didn't buy anything that day. Some bought on Tuesday. Some bought next week. A few searched for the brand a month later and bought then.

This obvious fact — that marketing effects don't all land on the day you spent the money — is what adstock is built to handle. And if your marketing mix model doesn't model it, you're not measuring marketing. You're measuring same-day clicks.

This post covers what adstock actually is, why every serious MMM includes it, the main mathematical forms it takes, and how to think about it whether you're choosing a tool or building your own. (For broader context on how MMM works, see our complete guide to marketing mix modeling.)

The core idea

Adstock — sometimes called carryover or decay — is the assumption that today's marketing effect equals today's spend plus some fraction of yesterday's effect. Written out:

adstocked_spend[t] = spend[t] + decay × adstocked_spend[t-1]

That's it. The "decay" parameter is a number between 0 and 1 that controls how long the effect lingers. Decay of 0 means the effect dies the instant the spend stops (every day stands alone). Decay of 0.9 means 90% of yesterday's effect carries into today, which then carries 90% into tomorrow, and so on — a long, slow tail.

This isn't just a modeling convenience. It's a description of how marketing actually works. People who see your ad don't all buy immediately. They store the impression, talk about it, search for the brand later, get retargeted, see another ad, and eventually convert. Adstock is the model's way of saying "the spend on day T is doing work on day T+1, T+2, T+3, and so on, with progressively less weight."

Why ignoring adstock wrecks your attribution

Picture two channels. You spend $1,000/week on TV for ten weeks. You spend $1,000/week on paid search for the same ten weeks. Sales rise gradually over the period.

Without adstock, the model has only one piece of information per channel per week: "$1,000 was spent." It tries to find a coefficient that, when multiplied by spend, predicts sales. Because both channels spent the same amount in the same weeks, and sales rose gradually, the model has no way to tell them apart. It splits credit roughly in half.

With adstock, the model sees something different. TV's adstocked spend ramps up — week 1 is $1,000, week 2 is $1,000 + 0.7 × $1,000 = $1,700, week 3 is $1,000 + 0.7 × $1,700 = $2,190, and so on. Paid search's adstocked spend, with a much faster decay, stays close to the actual weekly spend. Now the two channels have different shapes over time, and the model can fit them to whatever pattern best matches the sales curve. If the sales lift looks like a slow accumulation, TV gets credit. If it tracks the spend exactly, search does.

Without adstock, channels that should look different look identical to the model. Attribution becomes guesswork dressed up as math.

Geometric adstock: the workhorse

The simplest form is geometric adstock — the formula above, with one decay parameter per channel. It's called "geometric" because the weights on past spend form a geometric series: 1, decay, decay², decay³, and so on.

Geometric adstock has two big virtues. It only needs one parameter per channel, which keeps the model from running out of degrees of freedom. And it has a clean interpretation: a decay of 0.5 means the effect halves each period.

There's a related concept called "half-life" that's worth knowing. If your decay is d and your time period is one week, the half-life is log(0.5) / log(d) weeks. Decay of 0.5 → half-life of 1 week. Decay of 0.7 → half-life of about 2 weeks. Decay of 0.9 → half-life of about 6.6 weeks. Half-life is more intuitive than decay for most marketers, and a useful sanity check on whatever the model produces.

Other adstock forms (and when they matter)

Two extensions to geometric adstock show up in serious MMM work.

Delayed adstock lets the peak effect happen some number of periods after the spend. The math has an extra parameter that shifts where the peak lands. This matters for channels with consideration cycles. A B2B email that takes weeks to convert, a high-consideration purchase that requires research, a TV ad whose effect hits when the next shopping trip happens — these don't peak on day one. They build, peak, then decay.

Weibull adstock uses a more flexible weighting function that can capture both the build-up and decay phases with two parameters. It's strictly more expressive than geometric, but you pay for it with extra parameters per channel and a harder optimization. For most MMM use cases — especially when you have less than two years of data — geometric is plenty.

If you're building your own model, start with geometric. Add delayed or Weibull only if you have a specific channel where the geometric assumption visibly fails (the predicted vs actual chart shows the model getting the timing wrong) and you have enough data to support more parameters.

Estimating decay rates vs assuming them

Older MMM implementations had a media analyst pick decay rates by hand. They'd say "TV has a long tail, set decay to 0.85. Search is immediate, set it to 0.2." This works in the sense that it produces a number. It's also entirely arbitrary.

Modern MMM implementations estimate decay rates from the data, jointly with everything else. The model considers different decay values for each channel, sees which combination best explains the sales pattern, and reports the decay it found. The advantage is that you're not imposing your priors on the data. The cost is that with limited data, the estimates can be unstable.

The sweet spot is to estimate decay but constrain it with reasonable priors. If your model is willing to consider any decay between 0 and 1 with no preference, it'll happily report TV decay of 0.99 if that fits the noise in your data slightly better than 0.7 — even though 0.99 implies the effect of a single week's spend persists for years, which it doesn't. A weakly informative prior — "decay is probably between 0.3 and 0.9, with most weight in the middle" — keeps the model honest without forcing your assumptions on it.

This is one of the places where Bayesian methods really earn their keep. (See Bayesian priors in MMM for more on this.)

How to think about decay rates by channel

You should have rough expectations for what decay rates look like before you ever run a model. If your output disagrees wildly with these, that's a signal something is off.

| Channel type | Typical weekly decay | Why | |---|---|---| | Brand TV | 0.7 – 0.9 | Long awareness tail | | Direct response TV | 0.5 – 0.7 | Faster intent build | | Out-of-home | 0.6 – 0.8 | Repeated exposure, slow decay | | Paid social (prospecting) | 0.4 – 0.6 | Some delayed conversion | | Paid social (retargeting) | 0.1 – 0.3 | Mostly same-week | | Paid search (non-brand) | 0.1 – 0.3 | Intent-driven, immediate | | Paid search (brand) | 0.05 – 0.2 | Almost entirely same-week | | Email to existing list | 0.1 – 0.4 | Quick action, some tail | | Influencer / PR | 0.6 – 0.85 | Slow word-of-mouth | | Display | 0.3 – 0.6 | Mid-funnel persistence |

These are rough — they vary by industry, audience, and product. But they're the right order of magnitude. If your model returns decay of 0.95 for paid search, something is wrong: either you have a data problem, or your model is overfitting noise.

Adstock + saturation = the nonlinear core of MMM

Adstock alone isn't enough. Once you've applied adstock, you also need to model the fact that doubling effective spend doesn't double sales. The two transforms are usually applied together: adstock first, then saturation. This combined transformation is the heart of what makes MMM nonlinear, and it's what separates a real MMM from a linear regression with a marketing label.

For a deep dive on the saturation half, see our post on saturation curves in MMM.

Common mistakes

Skipping adstock entirely. This is the cardinal sin. Any "MMM" that fits a linear regression directly on raw spend, with no transformation, is not an MMM in any serious sense. It's a regression. If a tool can't tell you what its decay parameters look like, it isn't doing this.

Using the same decay for all channels. Some lightweight implementations apply a global decay (often 0.5) to every channel. This is better than nothing but worse than per-channel estimation. Channels have genuinely different carryover; treating them as identical sacrifices most of what adstock gives you.

Using decay rates that don't match your time period. A decay of 0.5 means very different things for daily vs weekly vs monthly data. Always know what time period your decay is operating on, and convert to half-life if it makes the number more intuitive.

Letting decay run unbounded. Without a sensible prior or constraint, optimization will sometimes produce decay values very close to 1. This implies the channel's effect persists nearly forever, which is almost never true and usually means the model is fitting trend or seasonality through the channel.

What to look for in a tool

If you're using rather than building, look for tools that:

  • Estimate decay parameters from data (not pick them by hand)
  • Allow per-channel decay (not a global value)
  • Apply Bayesian or regularization priors that prevent extreme decay values
  • Report the estimated decay rates so you can sanity-check them against your channel mix

CheapMMM does all of these — geometric adstock with per-channel decay, Bayesian-informed priors that keep estimates in plausible ranges, and decay parameters surfaced in the output so you can verify the model isn't doing anything absurd. But the more important point is that any tool you trust with budget decisions should do these things, regardless of who built it.

Try CheapMMM free — no login required