// diagnose
Incrementality And Mmm
Use when the user wants to know whether marketing spend actually caused conversions, rather than just preceded them — incrementality testing, holdout or geo tests, iROAS, or media mix modelling. Also use when the user mentions incrementality, holdout test, geo test, lift test, iROAS, incremental CAC, MMM, "is this channel actually working", or doubts about attributed conversions. Designs the test, sizes it, then reads it out honestly — including whether it was ever powerful enough to answer the question.
npx skills add sarojkjha/aaj-marketing-skills --skill incrementality-and-mmm// when to use it
Use when the user wants to know whether marketing spend actually caused conversions, rather than just preceded them — incrementality testing, holdout or geo tests, iROAS, or media mix modelling. Also use when the user mentions incrementality, holdout test, geo test, lift test, iROAS, incremental CAC, MMM, "is this channel actually working", or doubts about attributed conversions. Designs the test, sizes it, then reads it out honestly — including whether it was ever powerful enough to answer the question.
// what you give
Baseline conversion rate, the lift worth detecting, available daily traffic or eligible geos, channel spend, and value per conversion — or, for a readout, the control and treatment group sizes and conversions
// what you get
Required sample size and test duration with the cost of the holdout, or a readout giving incremental conversions, iROAS, incremental CAC, significance, and an explicit verdict on whether the test could ever have detected the effect
Incrementality & MMM
Answer the question attribution cannot: would this conversion have happened anyway?
Attribution models tell you which touchpoint preceded a conversion. They cannot tell you which touchpoint caused it, because they only observe the world where the ad ran. The gap between those two things is largest exactly where reported performance looks best — retargeting and branded search routinely show excellent attributed ROAS and much weaker incremental ROAS, because they intercept people who were already going to convert.
The only way to close that gap is to withhold the spend from a comparable group and measure the difference. That's uncomfortable — you're deliberately forgoing revenue to learn something — which is why most teams never do it, and why the ones that do usually reallocate budget afterwards.
The failure mode this skill exists to prevent is the underpowered test. A holdout that finds "no significant difference" when it was never large enough to detect a meaningful effect is not evidence the channel doesn't work. It gets reported as though it were, and budget moves on the strength of it.
When to use
The user is designing or reading a holdout, geo, or lift test — or questioning whether attributed conversions are real. For on-site A/B tests of a page or flow, use ab-test-significance; the statistics overlap but the design question is different. For reporting results upward, use marketing-report.
Before you start
- Read the brand/product context (
.agents/product-marketing.md) for the business model and conversion definition. - Fix the conversion definition first. Incrementality on a soft metric tells you little. Measure the thing with revenue attached.
- Get the real baseline rate, not a rounded estimate — sample size is highly sensitive to it.
- Decide the lift worth detecting before running anything. This is a business question, not a statistical one: below what lift would you not change the budget?
- Check you can actually hold out. Some channels can't be split cleanly. Geo tests exist for exactly that case.
Method
Design before you spend. Sample size follows from four inputs: baseline rate, the lift you care about, confidence, and power. Small lifts on low baselines need very large samples — a 5% lift on a 2% conversion rate needs hundreds of thousands per group, which for most Seed–Series B companies means the test is impossible and the honest answer is to test a bigger intervention.
Then hold everything else constant. A test contaminated by a pricing change, a competing campaign, or a seasonal shift measures nothing. Duration matters here: run at least one full weekly cycle, and be suspicious of tests running past six weeks, where drift becomes near-certain.
Then read it honestly. Three outcomes, not two:
- Incremental — significant lift. The spend caused conversions.
- Not significant, adequately powered — a real finding. The channel's attributed conversions are suspect.
- Inconclusive — the test could never have detected the effect you'd care about. This is not evidence of anything.
That third category is the one that gets misreported, and the engine calls it explicitly.
See resources/incrementality-guide.md for holdout vs geo test design, what to expect by channel, the MMM-lite section, and a worked example.
Run the engine
Design a test:
Paths assume you installed with
npx skills add. From a clone of this repo, useskills/incrementality-and-mmm/resources/…instead.
node .agents/skills/incrementality-and-mmm/resources/incrementality.js # demo
node .agents/skills/incrementality-and-mmm/resources/incrementality.js --baseline 2.5 --mde 15 --daily 4000 --value 400
node .agents/skills/incrementality-and-mmm/resources/incrementality.js --baseline 1.2 --mde 25 --power 0.90 --daily 20000
Read one out — supply --treat-conv and it switches mode:
node .agents/skills/incrementality-and-mmm/resources/incrementality.js --control-n 50000 --control-conv 1200 \
--treat-n 50000 --treat-conv 1380 --spend 15000 --value 400
node .agents/skills/incrementality-and-mmm/resources/incrementality.js --json --control-n 5000 --control-conv 120 \
--treat-n 5000 --treat-conv 132
node .agents/skills/incrementality-and-mmm/resources/incrementality.js --help
Design mode returns sample per group, duration, and the value you forgo by holding out — which is the number that decides whether the test is worth running. Readout mode returns lift, p-value, confidence interval, incremental conversions against the counterfactual, iROAS, incremental CAC, and the smallest lift the test could actually detect.
Workflow
- State the decision the test will inform. If no budget decision hangs on the result, don't run it.
- Set the lift worth detecting from that decision, not from what seems achievable.
- Run design mode. If the duration exceeds about six weeks, the test as specified isn't viable — either raise the detectable lift, use a geo test, or test a larger intervention.
- Weigh the holdout cost against the spend at stake. Withholding $300K to validate a $50K channel is the wrong trade.
- Freeze everything else for the window. Document what else was running so contamination is visible later.
- Run to the planned duration. Stopping when the result looks good inflates false positives — this is the single most common way lift tests mislead.
- Run readout mode. Report the verdict, not just the p-value.
- Act on iROAS, not attributed ROAS. Where they diverge sharply, trust the test.
Present the result
Lead with the verdict and iROAS — those drive the budget decision. Then the incremental conversions against the counterfactual, since that's the number people can reason about. Then significance and the detectable-lift caveat.
If the test was inconclusive, say so plainly and give the sample size that would have answered it. Do not let an inconclusive test be reported as a negative finding.
Guardrails & common mistakes
- Never report an underpowered null as "the channel doesn't work." It means the test was too small. The engine separates these deliberately.
- Don't stop early. Peeking and stopping on a favourable result badly inflates false positives. Fix the duration in advance and honour it.
- Attributed ROAS and iROAS are different numbers. Expect them to diverge most on retargeting and branded search, where attribution is most generous.
- Geo tests need comparable geos. Match on baseline conversion rate and volume, not just population. Unmatched geos produce differences that have nothing to do with the campaign.
- One change at a time. A test that alters spend and creative and landing page tells you something happened, not what.
- Results decay. An incrementality finding is a snapshot of a market, a creative, and a season. Re-test periodically rather than treating one result as permanent.
- Don't hold out so much that you damage the business. The design mode prices this; use it. A statistically ideal test that costs a quarter's pipeline is not a good test.
- MMM and incrementality answer different questions. MMM allocates across channels using historical data and is prone to correlation artefacts; incrementality establishes causation for one channel. Where they disagree, the experiment wins — and the honest use of MMM is to generate hypotheses that incrementality then tests.
Related AAJ resources
- Interactive tool: https://aajconsult.com/tools/ab-test-significance-calculator
- Interactive tool: https://aajconsult.com/tools/marketing-kpi-report
Related skills
ab-test-significance (on-site experiments — same statistics, different design question) · paid-media-budget-allocation (where the reallocation decision lands) · unit-economics (the value-per-conversion input this depends on) · marketing-report (reporting the result upward) · marketing-attribution (the model this is designed to check).
// see it run
Examples
// prompt
node resources/incrementality.js --control-n 50000 --control-conv 1200 --treat-n 50000 --treat-conv 1380 --spend 15000 --value 400
// result
AAJ · INCREMENTALITY READOUT INCREMENTAL — the lift is real at the chosen confidence level. RATES Control 2.40% (1,200 / 50,000) Treatment 2.76% (1,380 / 50,000) Relative lift 15.0% SIGNIFICANCE p-value 0.0003 significant Smallest lift this test could detect: 11.3% INCREMENTALITY Expected at control rate 1,200 conversions Actually observed 1,380 Incremental 180 Incremental value $72,000 iROAS 4.80x (spend $15,000) Incremental CAC $83
// faq
// install
npx skills add sarojkjha/aaj-marketing-skills --skill incrementality-and-mmm// run it
node .agents/skills/incrementality-and-mmm/resources/incrementality.js --demo// worked example
Get the worked example for incrementality-and-mmm
One email. The filled-in config, the output, and how to read it.
// sprint
Unit Economics & Retention Sprint — $3,500, 10 business days
This skill is one of the engines behind the Unit Economics & Retention Sprint — $3,500, ten business days.
LTV, CAC, payback and churn on your actual numbers — with a verdict, not a dashboard.
// human in the loop
Need a human in the loop?
AAJ builds the strategies, tools, and playbooks these skills are made of — with engagements for growth-stage and enterprise teams.
Skills