Skip to main content
Back to blog
Marketing Mix Modeling
Adstock
Bayesian Statistics
Priors
PyMC-Marketing

Half-Life Is Still the Parameter: Extending the Idea to Delayed Adstock

Geometric adstock assumes advertising works hardest the moment it lands. Delayed adstock lets the effect build first. That changes the curve, but it does not have to cost you the parameters people can actually reason about: you can still describe the response by when it peaks and how long it takes to move between half strength and that peak.

Jake Piekarski & Niall OultonAugust 18, 202612 min read

In the previous post, Half-Life Is the Parameter, we argued that geometric adstock becomes far easier to reason about once you stop putting priors on the retention rate α and start putting them on the half-life instead. The change was two lines of code. The argument was that weeks are a unit people can think in, and α is not.

That post quietly assumed something, though: that geometric adstock was the curve you wanted in the first place. So what happens when it is not?

The short answer, and the whole point of this one: you can change the adstock curve without giving up the interpretable parameterisation. With delayed adstock you arguably get more out of it, because the same trick hands you two quantities a marketer can argue about instead of one.

Geometric adstock is one shape, not the only one

Geometric adstock says the effect of advertising is largest immediately and then declines, every period, by the same proportion:

w(ℓ) = α

So the shape it can express is fixed: exposure, maximum effectiveness straight away, then decay. For plenty of channels and plenty of purchases that is a perfectly sensible story. Someone sees a promoted post, taps it, buys a t-shirt, and whatever effect remains next week is a fading remnant of that.

It is not universally plausible, though. When the purchase involves more consideration, a car, a mortgage, a holiday, a piece of B2B software, the sequence often runs differently: someone sees the advertising, awareness or consideration builds, they research it, they discuss it with whoever else has a say, and the purchase happens later. The strongest response is not necessarily in the first week.

For those cases you may want a curve that can build, peak, then decay. That is what delayed adstock offers. It is not a better kernel, and it is certainly not a rule that long purchase cycles need it. It is a shape that can be more plausible when you do not expect peak effectiveness immediately, and the honest way to choose between the two is to think about the behaviour you are modelling and then check what the data supports.

Geometric adstock asks one question: how quickly does the effect fade? Delayed adstock asks two: when does it peak, and how wide is the response around that peak? Holding on to the second question in units people understand is what this post is about.

The delayed kernel

PyMC-Marketing’s delayed adstock weights the lag ℓ periods after exposure with:

w(ℓ) = α(ℓ − θ)²
  • is the lag, in whatever periods your model runs on;
  • θ is where peak effectiveness sits;
  • α controls how quickly effectiveness falls away from that peak.

The difference from geometric is entirely in the exponent. Geometric raises α to the lag itself, so lag zero always wins and everything after it is smaller. Delayed raises α to the squared distance from θ, so the exponent is zero at θ and grows in both directions. The maximum moves to θ, and the curve is free to build before it gets there.

Same half-life, different peak
Both curves fall to half strength 2 weeks away from their peak. Only the peak has moved.
geometricpeak at lag 0delayedpeak at θ = 4
50%peak effectiveness0 wks24681012

Geometric adstock starts at its maximum and can only decline. Delayed adstock lets effectiveness build first, which is the shape you want when the purchase takes a while to happen.

That makes θ easy to describe: it is the time from exposure to peak effectiveness. Increase it and the whole response slides later in time.

α needs more care. Calling it a decay rate, which is fair enough for geometric adstock, is misleading here, because it no longer governs a one-directional decay. For delayed adstock α sets the width of the response around the peak. Push α towards one and effectiveness stays high for weeks either side of θ. Pull it down and the response concentrates into a spike at θ.

One consequence is worth stating before we go further. Because the exponent is a squared distance, the kernel is symmetric: w(θ − d) = w(θ + d) for any d. The build-up and the cool-down are the same shape, governed by the same number. Delayed adstock cannot represent a four-week build followed by a one-week collapse. If your channel genuinely behaves that way, this kernel is the wrong tool and no reparameterisation will rescue it.

α still does not survive contact with a meeting

Here is where the previous post comes back. “We think this channel’s delayed-adstock alpha is 0.94” is not a sentence anyone can push back on, and it is arguably worse than the geometric case. At least there, α was raised to a number of weeks, so a determined listener could work out what it meant. Here it is raised to a squared distance from a peak, which is not something anyone holds an intuition about.

So we ask the same question we asked last time. Can we parameterise the width of this response in time units instead? We can, and the derivation is barely longer.

Deriving the delayed half-life

Define h as the distance from the peak at which effectiveness has fallen to half. Then the delayed kernel can be written entirely in θ and h:

α = 2−1/h²
w(ℓ) = 2−((ℓ − θ)/h)²
How α follows from the definition of h

At the peak the exponent vanishes, so w(θ) = 1. h is the distance from that peak at which the response is half as strong:

w(θ + h) = ½ w(θ)

which is

α = ½

Take logs:

h² log α = log ½ = −log 2

and therefore

α = 2−1/h²
How that substitutes back into the kernel

Feed the same α into the delayed kernel:

w(ℓ) = α(ℓ − θ)²

and it simplifies directly to

w(ℓ) = 2−((ℓ − θ)/h)²

No approximation has been introduced. This is the same curve, written in a coordinate people can reason about.

This is not a new adstock curve. It is the same delayed-adstock kernel written in a different coordinate. Nothing has been approximated, nothing has been added, and the model class is identical. All that has changed is which number you ask a human, and a sampler, to work with.

What h actually means here

This is the sentence to hold on to: h is the time effectiveness takes to rise from half strength to its peak, and, because the delayed kernel is symmetric, the time it takes to fall from the peak back to half strength.

That is a real difference from the geometric case, and it is worth being pedantic about, because the parameter is called half-life in both. For geometric adstock, the half-life is a decay time measured from the peak at lag zero: peak to 50%, one direction only. For delayed adstock it is a half-width either side of θ: 50% up to the peak, and the peak back down to 50%. Same word, same underlying idea, slightly different reading.

Take θ = 4 weeks and h = 2 weeks, which by the mapping above means α = 0.841. The response is then at 50% of peak at week 2, at 100% at week 4, and back at 50% at week 6.

One number, both directions
A response with θ = 4 weeks and h = 2 weeks, as a share of its own peak.
50%100%50%week 2week 4week 6θ − hθθ + h
Because h is measured from the peak in either direction, the same number describes the build-up and the cool-down.

Which leaves two parameters you can put in front of a media team without translating anything: θ, when does the effect peak, and h, how long does it take to move between half strength and peak.

GeometricDelayed
Kernelαα(ℓ − θ)²
Peaklag 0around lag θ
Shapedecay onlybuild, peak, decay
Half-life meanspeak to 50%50% to peak, and peak to 50%
Mappingα = 2−1/hα = 2−1/h²

The idea survives the change of curve. Its precise interpretation adapts to the shape, which is exactly what you want from a parameterisation: it should describe the model you actually chose.

Try it yourself

The quickest way to feel the difference is to drag the sliders. The top two both control the width of the response, one in α and one in weeks. The third moves the peak.

Two questions, three dials
When does it peak, and how wide is it around that peak?
retention
α = 0.930
half-peak width
h = 3.1 weeks
peak effectiveness
θ = 4.0 weeks
50%100%θ = 4.00.97.10 wks48121620

Move θ and the whole response shifts through time. Move h and the response widens or narrows. Move α and you are changing that same width, but on a much less intuitive scale. The two hollow markers sit at half the peak, θ − h and θ + h.

Two things should stand out. Moving θ does not change the shape at all, it just slides it. And the α slider has that same “nothing, nothing, nothing, everything” feel it had in the last post, only more so.

Equal steps in α are not equal steps in anything you care about

Inverting the mapping gives the width implied by any α:

h(α) = √(log ½ / log α)

That square root is the problem in miniature. Take two moves of exactly the same size on the α scale, two hundredths each, and watch what they do:

Two identical steps in α…
…and what each one does to the width of the delayed response.
0.20 → 0.22
+0.02 weeks
0.97 → 0.99
+3.53 weeks
The same two-hundredth move carries roughly 174× the consequence at the top of the scale as it does in the middle.

The closer α gets to one, the more a seemingly trivial adjustment reshapes the response. And every broad, slow-building channel you care about lives up there, where the third decimal place starts deciding how many weeks of effectiveness your model believes in.

The same thing shows up if you walk through a family of curves. Below, both panels hold θ fixed. One takes even steps in α; the other takes even steps in h.

Equal steps in two coordinates
Peak held at θ = 4. In one panel α moves by 0.10 each time; in the other h moves by one week each time.
Equal steps in α
α = 0.50, 0.60, 0.70, 0.80 and 0.90, steps of 0.10
50%0 wks481216
implied half-peak width, weeks: 1.0, 1.2, 1.4, 1.8, 2.6
Equal steps in half-life
h = 1, 2, 3, 4 and 5 weeks, steps of 1
50%0 wks481216
implied α: 0.500, 0.841, 0.926, 0.958, 0.973

Stepping α, the curves bunch and then the last step does most of the work. Stepping h, the family fans out evenly. Equal steps in α do not mean equal steps in advertising memory, and for delayed adstock that memory is the width of effectiveness around its peak.

Stepping α by 0.10 each time, from 0.50 to 0.90, produces half-peak widths of 1.0, 1.2, 1.4, 1.8 and 2.6 weeks. The last of those four steps does more than the first three put together. Stepping h by one week at a time, from 1 to 5, needs α values of 0.500, 0.841, 0.926, 0.958 and 0.973, and produces a family that fans out evenly.

Priors are where this actually pays off

Better vocabulary is nice. The real reason to care is that the coordinate you choose determines whether the knowledge in people’s heads can get into the model at all.

A planner might tell you: “this campaign probably peaks around three weeks after exposure, and it is roughly half as strong a couple of weeks either side of that.” That is two statements, and delayed adstock has a parameter waiting for each of them. Peak timing is a prior on θ. Width around the peak is a prior on h. Both are checkable, and both are the kind of claim someone will happily argue with. Try writing the same belief as a Beta over α and nobody in the room can tell you whether you got it right.

What a prior on α believes about the width of the response
Common α priors pushed through h = √(log ½ / log α), next to a prior stated directly in weeks.
α ~ Beta(1, 3)PyMC-Marketing's default prior on αα ~ Uniform(0, 1)the flat, supposedly neutral choiceh ~ LogNormal(log 3, 0.3)stated directly in weeks
0 wks2468
PriorImplied half-peak width90% of the belief
α ~ Beta(1, 3)median 0.66 weeks0.41 to 1.23 weeks
α ~ Uniform(0, 1)median 1.00 weeks0.48 to 3.68 weeks
h ~ LogNormal(log 3, 0.3)median 3.00 weeks1.83 to 4.91 weeks

The α priors are not wrong so much as unexamined: both of them insist the response is half strength barely a week from its peak. The prior on the right says what a marketer would actually say.

A prior that looks simple on α can imply a highly non-obvious belief about the actual time-width of the response. The half-life parameterisation lets you state that belief directly.

The fix is still two lines of code

Nothing about the machinery changes. Sample the half-life, derive α from it, and hand α to the same delayed-adstock function as before. In PyMC:

python
halflife = pm.Gamma("halflife", mu=4.0, sigma=3.0)  # in weeks
alpha = pm.Deterministic(
    "alpha",
    pt.exp(pt.log(0.5) / halflife**2),
)
# Feed alpha, and your prior on theta, into delayed adstock unchanged.

Note the only difference from the geometric version: the squared half-life in the exponent. The adstock calculation itself is untouched. You have simply chosen to sample a parameter people understand and derive the awkward one from it.

Although you no longer have to write those two lines

Since we wrote the last post, this parameterisation has landed in PyMC-Marketing itself, for geometric adstock first and then for delayed. Pass a prior for halflife and the delayed kernel is parameterised by its half-peak width, with theta carrying on exactly as before:

python
adstock = DelayedAdstock(
    l_max=12,
    priors={
        "halflife": Prior("LogNormal", mu=np.log(3), sigma=0.3),
        "theta": Prior("HalfNormal", sigma=2),
    },
)

For weekly data, those two priors say the effect peaks a couple of weeks after exposure and takes about three weeks to move between half strength and its peak. The parametrisation is inferred from the presence of the halflife prior, and the trace will contain adstock_halflife where it used to contain adstock_alpha. You can also ask for it explicitly and take the defaults:

python
adstock = DelayedAdstock(l_max=12, parametrization="halflife")

The built-in half-life prior was chosen to reproduce the existing α default rather than to assert anything sensible about marketing: it implies a median half-life of about two thirds of a period. Put your own prior on halflife if you actually have a view.

A note on versions. Both half-life parametrisations landed after the 1.0.0 release, so at the time of writing they are on PyMC-Marketing’s main branch rather than in a published version. Until the next release, install from source to use them, or use the two-line PyMC version above, which works on any version.

Numbers your team can argue with

The reporting side gets richer too, because there are now two questions to answer rather than one:

QuestionParameter
When should this channel reach maximum effectiveness?θ
How long from half strength up to that peak?h
How long from the peak back down to half strength?h, again

To make that concrete, two shapes at opposite ends of the range. A short-consideration response might sit around θ ≈ 1 and h ≈ 1: peaking soon after exposure and fairly concentrated. A slower-build response might sit around θ ≈ 4 and h ≈ 3, which is an α of 0.926: peaking several weeks later, with effectiveness spread more broadly around that peak. These are illustrations to anchor your intuition about the two parameters, not defaults to adopt by channel, and certainly not a table to copy into a model.

“Peak around week four, half strength two or three weeks either side” is a sentence a marketer can challenge on the spot. “Theta of four and alpha of 0.926” technically says the same thing, and hides precisely the part they know something about.

What carries over from the geometric case

Most of the argument in the previous post was never really about geometric adstock, so it transfers without modification:

  • Put priors where the knowledge is. Your team has views about weeks. Ask them for weeks.
  • Report in units people can interpret. A posterior for h and θ can be read out loud in a meeting. A posterior for α needs a translation step that usually does not happen.
  • A tidy prior on α can imply an untidy belief about time. Uniform(0, 1) looks like the definition of neutrality and implies that the response is half strength within about a week of its peak.
  • Hierarchical priors get easier. “These two related channels probably peak at a similar time” and “brand channels probably have broader responses around their peak than performance channels” are natural statements about θ and h. In α space, their practical meaning shifts depending on where on the scale you happen to be.
  • Reparameterisation cannot create information. If the data cannot distinguish a narrow response from a broad one, the posterior should stay wide. Half-life just expresses that uncertainty in units where you can see it and act on it.
  • The coordinate change is exact. α = 2−1/h² is a substitution, not an approximation. The model class is untouched.

What we are not claiming

The previous post carried a benchmark: simulated weekly data, divergence counts, effective samples per second, posterior recovery of known half-lives. Those numbers were measured on geometric adstock, and we have not rerun the experiment for the delayed kernel, so we are not going to recycle them here.

The interpretability and prior-elicitation conclusions above hold exactly, because they are statements about the mapping and they follow from the algebra. The sampling argument is more of an expectation than a result: widths do get compressed against α = 1, and a coordinate where the quantity of interest moves linearly is usually a friendlier one to explore. Whether that translates into the same measured gains for delayed adstock is a question for an experiment we have not run, and we would rather flag the gap than quietly imply we filled it.

The fine print

  • Lags are integers. The kernel is continuous in its parameters but only ever evaluated at whole periods. With a non-integer θ or h, there may be no observed lag sitting exactly at the peak or at a half-peak point. The interpretation of the parameters does not change; you just cannot always point at the crossing.
  • Symmetry is an assumption, not a finding. w(θ − d) = w(θ + d) means h governs the build and the decay together. If your process needs a fast rise and a slow fade, or the reverse, you need a more flexible kernel such as a Weibull, not a different parameterisation of this one.
  • Respect l_max. If θ + h falls well outside the lag window, the implemented kernel cannot express the response your prior is describing. Widen the window, tighten the prior, or both, and do not leave much prior mass on shapes that get truncated.
  • Nothing happens before the exposure. Only lags of zero and above exist. If θ − h is negative, the left-hand side of the symmetric kernel is a mathematical fact with no causal meaning, and the observed response simply starts partway up the build. It is a sign that your peak is early relative to the width, not that the model is running backwards.
  • Normalisation is harmless here. With normalize=True, every weight is divided by the same total, so ratios to the peak survive untouched: w(θ ± h) / w(θ) is still exactly one half, and h still reads as a half-width in weeks.
  • Units follow the data. h and θ are measured in whatever frequency your model runs on. Weekly data makes them weeks, daily data makes them days. Everything above assumes weekly.

Choose the curve, then choose the coordinate

Geometric adstock was never the important part of the half-life argument. Interpretability was. Changing the response shape should not push you back into parameters that only the modeller can discuss, and with delayed adstock it does not have to. You still get to describe the response with two things anyone can reason about: when it peaks, and how wide it is around that peak. Those are θ and h.

“Alpha is 0.926” is a model parameter. “The effect peaks after four weeks and takes another three weeks to fall to half strength” is a business statement. The job of a good parameterisation is to move as much of the model as possible into the second language, because that is the only one in which someone can tell you that you are wrong.

Choose the adstock curve that fits the behaviour, and parameterise it in the language people actually use.

SIMBA builds on PyMC-Marketing for transparent Bayesian MMM. If you want to talk through which adstock shape fits your channels, and what to put on θ and h, book a call.

Published on August 18, 2026 by Jake Piekarski and Niall Oulton

All posts