Bayesian MMM: how priors and data combine in a marketing mix model

A Bayesian marketing mix model doesn't remove assumptions, it writes them down as priors. Here's how priors and sales data combine into an ROI you can defend, and how to stop the prior quietly making the decision for you.

Mike Taylor By Mike Taylor · Updated · 12 min read

A Bayesian MMM is a marketing mix model estimated with Bayesian inference: you state a prior distribution for each parameter (a channel’s ROI, how long its effect carries over, how fast it saturates), the model combines those priors with the likelihood of your sales data, and you get back a posterior distribution for every parameter instead of a single number. In practice that means each channel’s return arrives as a range with probabilities attached, and your assumptions are written down where someone can argue with them rather than buried in the code.

I’ve built marketing mix models for companies like Monzo, Booking.com and The AA, and advised Google and Recast on MMM, and the biggest shift I’ve seen over that time is from models that hand you one coefficient per channel to models that hand you a distribution. Bayesian marketing mix modeling isn’t new (Google’s researchers published the template in 2017), but it moved into the mainstream once PyMC Labs built PyMC-Marketing and Google released Meridian. If you’re new to MMM in general, start with what marketing mix modeling is and come back here; this page assumes you know a model splits sales into baseline and channel contributions.

What a Bayesian MMM actually is

A marketing mix model is a regression of sales on media, price, promotions, seasonality and whatever else moves demand. The classical way to fit it is to find the coefficients that minimize squared error (ordinary least squares) or a penalized version of it (ridge regression), which gives you one best guess per parameter and a standard error you have to interpret carefully. A Bayesian MMM fits the same kind of structure, usually with adstock for carryover and a saturation curve for diminishing returns, but it treats every unknown as a random variable with its own distribution.

The reason this matters for marketing is that MMM data are almost always too thin for the question being asked. You might have 104 weekly rows, eight channels that each need three or four parameters, plus trend, seasonality and controls, and two of those channels were always switched on together (the multicollinearity problem). The data alone can’t pin down every number. A classical model still produces an answer in that situation, it just doesn’t tell you how much of the answer came from the data and how much from arbitrary choices in the code. A Bayesian model forces those choices into the open as priors, and the posterior tells you how much the data changed them.

It’s worth being clear that “Bayesian” is a way of estimating the model, not a different theory of marketing. The adstock and saturation functions in the Jin et al. (2017) paper are the same shapes Robyn uses; what changes is that you get uncertainty on each of them, and you can feed in outside evidence like an experiment.

Priors, likelihood and posterior for a channel’s ROI

There are three pieces, and the easiest way to understand them is with one parameter you care about: the ROI of a single channel (revenue returned per dollar spent).

  • Prior: what you believe about the ROI before the model sees this sales data, written as a distribution. “Probably between 0.5 and 3, most likely around 1.5” is a prior.
  • Likelihood: how probable the observed sales are for each possible ROI value, given the model’s structure. For intuition you can think of it as the data’s own estimate plus its standard error.
  • Posterior: the prior multiplied by the likelihood and rescaled so it sums to one. It’s the updated belief, and everything you report (the ROI, the interval, the probability the channel loses money) comes from it.

In the simplest case, where both the prior and the data estimate are normal distributions, the posterior mean is a precision-weighted average of the two. Precision is one over the variance, so whichever source is more certain gets more weight:

μpost=μprior/σprior2+β^/se21/σprior2+1/se2\mu_{post} = \frac{\mu_{prior}/\sigma_{prior}^2 + \hat{\beta}/se^2}{1/\sigma_{prior}^2 + 1/se^2}

That formula is the whole intuition behind Bayesian MMM in one line. When the data are weak (a large standard error, because the channel barely varied or moved in lockstep with another one) the prior dominates. When the data are strong, the prior hardly matters. Try it with your own numbers:

Interactive
Combine a prior with the data for one channel's ROI

Set what you believed about a channel's return before the model saw your sales data, then set what the data alone says and how precisely. The posterior is the compromise, and you can see exactly how far it moved.

Posterior mean ROI
-
90% credible interval
-
Moved toward data
-
P(ROI < 1)
-

One parameter, a normal likelihood for the data estimate (estimate ± standard error) and either a normal prior or a lognormal prior specified by its mean and standard deviation. The posterior is computed exactly on a grid, so it is what MCMC would approximate for this one-parameter problem. Invented default numbers; type in your own.

With the defaults, a prior centered on 1.5 meets a noisy data estimate of 3.0, and the posterior lands around 1.7, much closer to the prior than to the data. Switch to “Strong data” and the same prior barely holds the posterior back. That’s the behavior you want, but it also shows the risk: with weak data, whoever wrote the prior effectively wrote the answer. The lognormal option matters because ROI can’t sensibly be negative for most paid media, and it’s the family Meridian uses for its ROI priors. Click “Meridian’s default ROI prior” to load the library’s default, LogNormal(0.2, 0.9) on the log scale, which has a median ROI of about 1.2, a mean of about 1.8 and a long right tail.

How MCMC gets you the posterior

For one parameter you can compute the posterior exactly on a grid, which is what the widget does. A real MMM has dozens to thousands of parameters (every channel’s ROI, decay and saturation, every seasonality term, and in a geo model all of those per region), and there’s no formula for the joint posterior. Markov chain Monte Carlo (MCMC) solves this by wandering through parameter space in a way that spends time in each region in proportion to its posterior probability, so the thousands of draws it keeps can be treated as a sample from the posterior. Meridian and PyMC-Marketing both use the No-U-Turn sampler (NUTS), a version of Hamiltonian Monte Carlo that uses gradients to take long, efficient steps, and you check that several independent chains agree using the R-hat statistic (values close to 1.0 mean the chains converged). If you want the mechanics in more depth, the Bayesian MCMC brief covers them; for marketing decisions, the thing to remember is that MCMC is slower than least squares (minutes to hours rather than seconds) and that a model whose chains disagree hasn’t finished, however nice its charts look.

Credible intervals are the point of the exercise

The output of a Bayesian MMM is a set of posterior draws, and the most useful summary of them is a credible interval: the range that contains, say, 90 percent of the posterior probability for a channel’s ROI. A 90 percent credible interval of 1.2 to 2.8 means the model, given its priors and structure, thinks there’s a 90 percent chance the ROI is in that range. That is the sentence most marketers think a frequentist confidence interval says, and it’s one reason Bayesian output is easier to explain to a CFO.

The draws also let you answer the questions a budget meeting actually asks. What’s the probability this channel’s ROI is below 1, so the last quarter’s spend lost money? What’s the probability social beats search at the margin? You compute each by counting the share of posterior draws where the statement is true, and you carry the uncertainty all the way through to the budget allocation rather than optimizing on point estimates and pretending the result is precise. I’d rather show a decision-maker a range that’s honest than a point estimate that’s tidy.

However, a credible interval is only as good as the model it comes from. If you left out a promotion that coincided with your TV bursts, the posterior can be narrow and confidently wrong. The interval describes uncertainty within the model’s assumptions, not uncertainty about whether those assumptions are right, which is why validating the model still matters.

Check your priors before you fit: prior predictive checks

A prior on an internal coefficient is hard to judge by eye. What does a HalfNormal(2) on a scaled media coefficient mean for revenue? Nobody in marketing knows, which is exactly why the prior predictive check exists: you simulate sales from the model using only the priors (before it sees the outcome data) and look at what comes out. If the priors imply weeks where paid social alone drives ten times your total revenue, or ROIs of 40, they’re not “uninformative”, they’re wrong.

PyMC-Marketing makes this a first-class step with sample_prior_predictive and a plotting helper, and its example notebook sets channel priors in proportion to each channel’s share of spend. Meridian sidesteps part of the problem by letting you put the prior on ROI itself, which is a quantity a marketer can reason about, and its documentation tells you to plot the priors and check their percentiles against your expectations before running the analysis. Either way, the habit is the same: look at what your priors imply in business units before you fit, then compare prior and posterior afterwards to see where the data actually spoke.

Informative priors from experiments

The best prior is one you earned. If you ran a geo-lift test or a conversion lift study last quarter that estimated a channel’s incremental ROI at 1.4 with a standard error of 0.3, that’s real evidence, and a Bayesian MMM can use it directly as the prior for that channel. Meridian’s documentation describes a calibrated prior as a “guardrail”, and PyMC-Marketing can add lift-test measurements to the likelihood. I go through both routes, and the trade-offs between them, on the MMM calibration page.

The catch is that an experiment answers a slightly different question from the one the model asks. A four-week test in eight regions during a promotion measures something close to, but not identical to, the channel’s average ROI across two years nationally. Meridian’s guidance says plainly that there is no single formula for translating an experiment into a prior, and that doing so adds a layer of uncertainty beyond the experiment’s own standard error, so the prior should usually be wider than the test’s error bars. In the widget, that’s the difference between setting the prior SD to the experiment’s 0.3 and setting it to 0.5: the second admits the test was a cousin of the question, not a twin. Also keep a record of which experiments went into which priors, so nobody later presents the model’s agreement with that same experiment as independent confirmation.

Hierarchical Bayesian models for geo data

If you have sales and media by region, a hierarchical Bayesian model is usually the biggest single improvement you can make. Instead of fitting one national model (few rows) or a separate model per region (few rows each, and wildly different answers), you estimate a media effect for every region while assuming those regional effects come from a shared distribution. Regions with lots of signal get estimates close to their own data; regions with little signal get pulled toward the overall average. That’s called partial pooling, and it’s the same idea as the prior-and-data compromise in the widget, applied at the level of regions.

Shared distributionaverage effect, spread across regionsNorth effectSouth effectEast effectWest effectSmall regionpulled to average104 weeks104 weeks104 weeks104 weeksnoisy, few salesRegional sales and media data (the likelihood for each region)
A hierarchical Bayesian model: each region's media effect is drawn from a shared distribution whose mean and spread are themselves estimated, so thin regions borrow strength from the rest. Source: Vexpower.

Google’s researchers showed the payoff in their 2017 paper on geo-level Bayesian hierarchical media mix modeling: with sub-national data the model generally produced tighter credible intervals than a national-only model, because the extra rows and the extra variation in spend across regions carry real information. Meridian is built around this structure; its README encourages geo-level data whenever it’s available, though it can also fit a national-level model. The catch is the assumption baked into the shared distribution: regions have to respond to media in broadly similar ways for pooling to help. If one region is structurally different (a different product range, a competitor that only operates there), pooling will drag its estimate toward an average that doesn’t describe it. The geo models brief has more on preparing regional data.

Bayesian regression, ridge regression and what Robyn does

People often ask whether Meta’s Robyn is Bayesian. It isn’t, but it’s closer than it looks. Robyn fits ridge regression, which adds a penalty on the size of the coefficients, and that penalty is mathematically the same as a Bayesian regression with a normal prior centered on zero for every coefficient (Robyn’s own docs make this point). What Robyn doesn’t do is sample a posterior: it searches over adstock and saturation hyperparameters with the Nevergrad optimizer and gives you a set of candidate models on a Pareto front instead of a distribution over parameters. The ridge regression page shows the shrinkage in action.

So the practical difference isn’t “priors versus no priors”. Ridge has a prior; it’s just the same prior for every channel, centered on zero, set by a tuning parameter rather than by evidence. Bayesian regression lets you give each channel its own prior, informed by experiments or plausible business ranges, and gives you a full posterior to report uncertainty from. That flexibility is the strength and the risk at once.

Which MMM libraries are Bayesian

Here’s where the main open-source options stand as of October 2026. The open-source MMM library comparison goes into more depth on each.

LibraryBayesian?InferenceNotes
Google MeridianYesMCMC (No-U-Turn sampler)Priors set directly on ROI (default LogNormal(0.2, 0.9)); geo-level hierarchical by design; experiment calibration through ROI priors.
PyMC-MarketingYesNUTS via PyMC, with nutpie, NumPyro or BlackJax samplersComposable adstock and saturation (e.g. GeometricAdstock, LogisticSaturation); prior predictive checks; lift-test and ROAS calibration; geo dimensions.
LightweightMMMYesNUTS via NumPyroNo longer supported; Google archived the repository in January 2026 and recommends Meridian.
Uber OrbitYesStan (via CmdStanPy)A Bayesian time-series package rather than an MMM library, sometimes used for time-varying coefficient models.
Meta RobynNoRidge regression + NevergradRidge equals a zero-centered Gaussian prior; multi-objective model selection instead of a posterior.

Vexpower’s earlier MMM path taught LightweightMMM and Orbit alongside Robyn, and if you’re starting today I’d point a Python team at Meridian or PyMC-Marketing. If you’d rather learn the ideas before the libraries, the marketing mix modeling course builds intuition for priors with one invented brand before any code.

Use priors deliberately, because a weakly identified model still makes assumptions

The lesson I most want people to take from Bayesian MMM is the one in the course’s “Make your prior assumptions visible” lesson: a weakly identified model still makes assumptions. When two channels always move together, the data can’t separate them, and something decides the split. In a classical model it’s an accident of the optimizer or the penalty; in a Bayesian model it’s the prior. A “very wide” prior isn’t automatically neutral either. A wide normal prior on a scaled coefficient can put substantial probability on ROIs no business has ever seen, and a wide prior on one parameter can imply a narrow, strange belief about another quantity you care about.

That means comparing the prior and posterior for every channel, and reading the comparison in context. A big shift suggests the data were informative. A small shift could mean the data agreed with the prior, or that the data were too weak to say anything, or that the prior was too tight to let them, and those three need very different responses. The course’s invented Northstar case has exactly this situation: two channels with too little independent variation, where the honest output is a wide posterior and a proposal for a test, not a confident reallocation.

Here’s the checklist I’d use before trusting a Bayesian marketing mix model’s numbers:

If the data really can’t separate two channels, no prior choice fixes that; it only decides who gets the credit. The honest move is to say so, report the wide interval, and design the experiment that would narrow it, which is where calibrating your MMM with experiments comes back in.

Frequently asked questions

What is a Bayesian MMM?

A Bayesian MMM is a marketing mix model estimated with Bayesian inference. You state prior distributions for parameters such as each channel's ROI, adstock decay and saturation, the model combines them with the likelihood of your sales data, and the result is a posterior distribution for every parameter rather than a single point estimate.

What is the difference between a prior and a posterior in marketing mix modeling?

The prior is what you believe about a parameter, such as a channel's ROI, before the model sees the outcome data. The posterior is the updated belief after combining that prior with the data. If the data are informative the posterior moves toward what the data say; if they are weak the posterior stays close to the prior.

Is Robyn a Bayesian MMM?

No. Meta's Robyn fits ridge regression and tunes its hyperparameters with the Nevergrad optimizer. Ridge regression is mathematically equivalent to a Bayesian model with a zero-centered Gaussian prior on the coefficients, but Robyn does not sample a posterior with MCMC. Google's Meridian and PyMC-Marketing are the main open-source Bayesian MMM libraries.

What is a hierarchical Bayesian model in MMM?

A hierarchical Bayesian model estimates a parameter for each group, such as each region's media effect, while assuming those group effects are drawn from a shared distribution. Regions with little data are pulled toward the overall average (partial pooling), which usually gives tighter and more stable estimates than fitting each region alone or pooling everything nationally.

How do you choose priors for a marketing mix model?

Start from evidence: incrementality experiments, previous models and plausible business ranges for ROI. Put priors on quantities the business understands, such as ROI, then run a prior predictive check to see whether the implied sales and returns are plausible. Finally, refit with another defensible prior and record whether the recommendation changes.

What is a credible interval?

A credible interval is a range that contains a parameter with a stated probability under the model and its priors. A 90 percent credible interval for ROI of 1.2 to 2.8 means the model puts 90 percent of its posterior probability between those values, which is the statement most marketers wrongly assume a confidence interval makes.

References

  1. Jin, Wang, Sun, Chan and Koehler (2017), Bayesian Methods for Media Mix Modeling with Carryover and Shape Effects The Google paper that set the template for Bayesian MMM with adstock and Hill saturation.
  2. Sun, Wang, Jin, Chan and Koehler (2017), Geo-level Bayesian Hierarchical Media Mix Modeling Geo-level hierarchical model; tighter credible intervals than national-only models.
  3. Google Meridian: default prior distributions Default ROI prior LogNormal(0.2, 0.9).
  4. Google Meridian: ROI priors and calibration Turning experiments into ROI priors; lognormal helpers; the 'guardrail' framing.
  5. Google Meridian: Bayesian inference MCMC with the No-U-Turn sampler; R-hat convergence checks.
  6. Google Meridian: amount of data needed Data points per parameter; partial pooling in geo models.
  7. PyMC-Marketing README and MMM example notebook MMM class, GeometricAdstock, LogisticSaturation, prior predictive checks, NUTS samplers, lift-test calibration.
  8. google/lightweight_mmm on GitHub No longer supported; repository archived in January 2026; recommends Meridian.
  9. Robyn documentation: features Ridge regression with Nevergrad; ridge equivalent to a Gaussian prior.
  10. Uber Orbit on GitHub Bayesian time-series forecasting and inference package.
Mike Taylor
Mike Taylor

I've built marketing mix models for Monzo Bank, Booking.com, Time Out, The AA and others, advised Google, Appsflyer and Recast on MMM, and teach marketing mix modeling on LinkedIn Learning. Before that I co-founded a 50-person growth marketing agency. I write the Vexpower MMM course.

Keep reading

Learn MMM by doing itThe Vexpower course walks through thirty lessons on one invented brand, with simulators, Python labs and a decision case you can defend.
See the course