Optimization and Scenario Simulation
Track 3 - Advanced · Module 3.3
All analysts
Course home
Learning ObjectivesModule 3.3 · ~40 min
Read a response curve: locate current spend, read the mROI as the local slope, and identify the diminishing-returns knee.
Explain what a portfolio optimizer does (reallocate a fixed budget to maximise incremental outcome under constraints) and why the optimum equalises marginal ROI across funded channels.
Distinguish portfolio optimization from flighting optimization (how much vs when), and both from scenario simulation (predicting outcomes for a stated budget).
An honest note before we start
This is the least-resourced module in the course. No internal document explains how this program's optimizer actually works - the Pre-Read names "Investment Optimisation" as a deliverable pillar and the glossary defines "Optimization & Simulation" in one line, but the mechanics are undocumented. What follows is authored from the response-curve exports the optimizer demonstrably consumes (the RC_Curve_Data files) plus standard marketing-science method. Everything program-specific about the optimizer carries a verify marker for the Gopi / Omkar SME session; treat the general method as solid and the implementation specifics as provisional.
Reading a response curve

A response curve is the fitted model played back as a menu: for one channel (or platform, or campaign), what cumulative incremental sales would each level of spend buy? Spend runs along the x-axis, cumulative incremental sales up the y-axis. Because of the adstock and Hill transformations baked into the fit (module 1.5), the curve rises steeply at low spend and flattens as the channel saturates - the shape the Pre-Read glossary summarises as "diminishing curve showing the response".

Three readings matter:

  • The height at your current spend is the channel's total incremental contribution - divide by spend and you have average ROI, the backward-looking number.
  • The slope at any point is the mROI at that spend level - what the next unit of money buys. This is the forward-looking number, and it falls continuously as you move right. The mROI decision rule from module 0.3 (above 1 invest, at 1 hold, below 1 reduce) is simply a statement about where on this curve you are standing.
  • The knee is the region where the slope decays fastest - before it, spend buys sales efficiently; after it, each increment buys visibly less. There is no single mathematical point (the curve is smooth), but the knee is where a planner's eye should snag: spending far past it needs a justification other than short-term sales.

The program exports these curves as RC_Curve_Data files at every modelled level. Their columns: step (the index along the spend grid), converted_spend (the spend level at that step), incremental_sales_vol / incremental_sales_val (the response in volume and value), total_imp (the impressions that spend buys), and mroi (the marginal ROI at that step - the slope, precomputed for you). The exports come in combined, no-aggregation, and year-vintage variants, so a curve can be read for the blended two-year fit or for a single modelled year. When you open one, you are looking at the literal raw material the optimizer consumes.

Check with SMEGopi / Omkar
Confirm whether optimization runs on ST response curves only or on ST+LT combined curves - the RC_Curve_Data exports exist on both sides of the model, and whether long-term (brand-health-routed) returns enter the allocation objective changes recommendations materially for upper-funnel channels.
Response curves: the optimizer's raw material
Five synthetic channels. Each curve is the RC_Curve_Data export shape: spend step vs cumulative incremental sales.
Allocate the budget yourself, then let the optimizer do it
Fixed total budget. Watch total incremental sales and per-channel marginal ROI as you move money.
$600k
Total incremental sales
0
vs equal split
ChannelSpendmROI
The allocation rule
At the optimum, marginal ROI is (nearly) equal across all funded channels. If one channel's next dollar returns more than another's, moving a dollar between them raises the total. The optimizer just repeats that move until no profitable move remains, subject to any floor/ceiling constraints the client sets.
Portfolio optimization: equalise the margins

The interactive allocator above is the whole idea in miniature: take a fixed budget, split it equally across the channels, then press optimize and watch money drain from flat curves into steep ones until every funded channel's mROI converges to the same value. Split it badly by hand first - the mROI readouts will disagree, and their disagreement is exactly the money being left on the table.

Portfolio optimization is the formal version: given a fixed total budget and one response curve per channel, choose the spend per channel that maximises total incremental outcome, subject to constraints. The optimum has a famous shape, worth internalising in words rather than algebra (it is the Lagrangian condition from managerial economics): at the optimum, every channel that receives discretionary money earns the same mROI on its last unit of spend - channels pinned at a floor or ceiling excepted. The reasoning is a simple exchange argument: if channel A's marginal unit earns 1.4 and channel B's earns 0.9, moving money from B to A gains you 0.5 per unit moved, so the current split cannot be optimal; keep moving money until the two marginal returns meet. Applied across all channels simultaneously, that stopping condition is the optimum.

A worked miniature with fabricated numbers - two channels, a fixed budget of 10 units, mROI at each incremental unit:

Spend unitChannel A mROIChannel B mROI
1st3.02.0
2nd2.51.7
3rd2.11.4
4th1.71.2
5th1.41.0
6th1.10.9
7th0.90.8

Allocating the 10 units greedily to whichever channel offers the higher next-unit mROI gives A six units and B four - at which point A's next unit earns 0.9 and B's earns 1.0, as close to equal as the grid allows. An equal 5-5 split would fund B's fifth unit (1.0) while leaving A's sixth (1.1) unfunded - strictly worse. Note what the optimizer never did: it never looked at average ROI. Channel A's headline ROI could be lower than B's and the allocation logic would not change; only the margins matter.

Constraints are where the textbook meets the client. Typical constraint sets in MMM practice:

  • Channel floors and ceilings - a minimum presence the brand will not go below (commitments, share-of-voice defence) and a maximum the market can absorb or the team can execute.
  • Maximum change vs last year - e.g. no channel moves more than some percentage from its current spend, keeping the recommendation inside the range where the fitted curve is trustworthy and the plan is organisationally sellable. This one matters statistically as well as politically: response curves are least reliable far from observed spend levels.
  • Fixed or protected lines - spend that is contractually committed and simply not on the table.

Every binding constraint costs outcome relative to the unconstrained optimum - a useful client conversation in itself ("keeping the TV floor costs you X in expected incremental sales").

Check with SMEGopi / Omkar
Confirm what solver the production optimizer actually uses (grid/greedy over the RC step tables, scipy-style constrained optimization, or something else) - the equalize-marginal-ROI account above is the standard method, not a description of the code.
Check with SMEGopi / Omkar
Confirm which constraint set is standard for this account (floors/ceilings? max percentage change vs last year? per-BG or per-platform constraints?) - the list above is generic MMM practice, not this program's documented default.
Flighting: when, not just how much

Portfolio optimization answers "how much per channel per year". Flighting optimization - a named topic in Gopi and Omkar's bootcamp session - answers the next question: given a channel's budget, how should it be spread across the weeks? The tension it manages is between burst flighting (concentrate spend in heavy pulses) and continuity (spread it thin and constant), and the physics of the trade-off comes from the two transformations you already know:

  • Adstock argues for spacing. A burst keeps working after it ends - the decay tail carries effect into the quiet weeks. A channel with a high adstock alpha (TV-like, slow decay) can go dark between pulses and coast on carryover; a channel with fast decay (search-like) stops working almost the moment spend stops, arguing for continuity.
  • Saturation argues against piling up. Within any single week, the Hill curve applies - the tenth unit of spend in one week buys less than the first. Concentrating too much budget into one pulse pushes each burst week deep past the knee, wasting money that would have earned more in an empty week.

Good flighting balances the two: pulses heavy enough to clear response thresholds, spaced so the adstock tail bridges the gaps, never so heavy that in-week saturation bites. Seasonality adds the final layer - the same GRP buys more sales in a high-demand week, so pulses should lean into seasonal peaks.

Check with SMEGopi / Omkar
Confirm how flighting optimization is actually implemented in this program (a weekly-grain optimizer over the fitted transforms? heuristic guidance off the alpha/beta parameters? a separate tool?) - nothing internal documents it beyond the session title.
Scenario simulation: the model played forward

The third deliverable in this family is the simplest to define - the Pre-Read glossary's entry for "Optimization & Simulation" reads, in full, "Predict outcomes for different budget scenarios". Scenario simulation takes a hypothetical budget - the client's draft plan, next cycle's proposal, a 10%-cut stress test - runs it through the fitted model's transformations and response curves, and reports the predicted sales, contributions and ROIs that would result. No search, no optimum: the client states the scenario, the model prices it.

The relationship between the three is worth stating cleanly, because clients blur them constantly. Simulation evaluates one stated plan. Portfolio optimization searches across plans for the best one. Flighting optimises the timing inside a plan. A typical engagement runs them in that reverse order: optimize to produce a recommendation, then simulate the client's counter-proposal alongside it, then flight whatever is agreed.

Every simulated scenario inherits the model's validation status. A scenario far outside historical spend ranges is an extrapolation the response curves were never fitted on - flag it as such rather than quoting it with the same confidence as an in-range scenario. This is module 3.1's MAPE discipline applied forward.
Check with SMEGopi / Omkar
Confirm how simulation scenarios are packaged for clients on this account (a standing simulator tool, a deck section with fixed scenario sets, ad hoc runs on request?) and how many scenarios a standard read-out carries.
The industry lens

For external grounding, the closest public analogue to this material is Google Meridian's budget-optimizer documentation, which walks the same pattern in the open: response curves per channel derived from a fitted MMM, a fixed-budget reallocation under channel-level constraints, and scenario comparison against the current plan. Read it for the method, not the model - Meridian's underlying MMM is Bayesian and this program's is not (module 3.5 covers that contrast properly), and the name overlap with this account's internal "Meridian" report design system is pure coincidence. The equal-marginal-returns allocation rule itself is far older than MMM: it is the standard resource-allocation result from managerial economics, and any text's treatment of allocating a fixed input across uses with diminishing returns is describing exactly what the allocator above does.

Check Yourself
On a response curve, where do you read a channel's mROI at its current spend?
Why: height ÷ spend is average ROI, the backward-looking number. mROI is the derivative - what the NEXT unit of spend buys - and it is the slope at the point where you stand. The RC_Curve_Data export carries it as its own column so you never have to differentiate by eye.
After a portfolio optimization run with a floor on Print, the results show TV, Digital Video and Paid Social all at mROI 1.15, while Print sits at mROI 0.6. Is this solution optimal?
Why: the equal-mROI condition applies to channels with discretionary money. Print's floor forces it to hold spend the optimizer would otherwise remove, so its marginal return sits below the common level - and the gap (1.15 vs 0.6 on the marginal unit) is precisely the price of the floor, a number worth showing the client.
The client sends next year's draft media plan and asks "what would this deliver?" Which tool answers, and what does it NOT do?
Why: "price this plan" is simulation: one stated scenario, evaluated. Optimization would answer a different question ("what plan should we run?"). In practice you often deliver both side by side - the client's scenario and the optimized one - and the gap between them is the value story.
A channel has very fast adstock decay (low alpha) and saturates quickly within a week (aggressive Hill curve). What flighting pattern does that combination argue for?
Why: burst flighting is financed by the adstock tail - with fast decay there is no tail, so dark weeks are truly dark. And quick in-week saturation punishes pile-ups. Both forces point the same way: spread it. The burst logic belongs to slow-decay, slow-saturating channels like TV.
Sources
Authored from:
  • RC_Curve_Data export structure from the sample ST/LT archives (columns: step, converted_spend, incremental_sales_vol/val, total_imp, mroi; combined / no-aggregation / year-vintage variants; per modelled level) - structure only, per SOURCE_MAP.md; no values used
  • UL_Rapid ROI_Pre-Read_Document 1.pptx slide 8 (glossary: Response curve, Saturation, "Optimization & Simulation: predict outcomes for different budget scenarios"), slide 9 (mROI decision rule), slide 7 ("Investment Optimisation" named as a deliverable pillar - mechanics not shown, confirming the gap)
  • Training Plan_MMX.xlsx "Optimization" and "Simulation" sessions (Gopi & Omkar): portfolio optimization, digital vs traditional, specific-goal optimisation, flighting optimisation - session topics only, no session material exists in the folder
  • External: Google Meridian public budget-optimizer documentation (closest public methodological analogue; this program's model is NOT Bayesian and the name overlap with the account's internal Meridian report design system is coincidental); standard equal-marginal-returns budget allocation from managerial economics
All tables and worked numbers are fabricated for teaching. Program-specific optimizer mechanics are unverified pending the Gopi / Omkar session - see the five verify markers above.