What We're Actually Asking

Budget allocation isn't about finding the "best" channel and giving it all your money. It's about finding the right balance—the mix that maximizes total return given the unique characteristics of each channel.

The key insight: every channel eventually hits diminishing returns. The first million dollars you spend on TV might be highly effective, but the tenth million is much less so. Smart allocation means finding where each additional dollar has the biggest impact.

The Garden Analogy

Imagine you have a limited water supply for your garden. Some plants are already well-watered—giving them more won't help much because they're saturated. Other plants are thirsty and would flourish with extra water.

Smart gardening means identifying the thirsty plants. Budget optimization works the same way: find the channels that still have room to grow.

The Core Concepts

2.1 Diminishing Returns

Diminishing returns means each additional dollar of spend produces less incremental outcome than the previous dollar. This is nearly universal in marketing:

Interactive: Watch Diminishing Returns in Action

Drag the slider to see how effectiveness changes as spend increases.

$50K
Total Response
$85K
Average ROI
1.70
Marginal ROI
0.95

2.2 Saturation Curves

A saturation curve shows the relationship between spend and response for a channel. The curve's shape tells you how quickly diminishing returns kick in.

Interactive: Compare Channel Saturation Curves

Each channel has a different curve shape. Some saturate quickly (steep early, flat later); others have more linear response. The vertical markers show current spend levels.

Reading this chart: X-axis is spend, Y-axis is response (incremental sales). The steeper the curve, the more effective at that spend level. Flattening = diminishing returns. Vertical dashed lines show current spend for each channel.

2.3 Marginal vs. Average ROI

This is the most important distinction for budget decisions:

Average ROI vs. Marginal ROI

Average ROI = Total return ÷ Total spend. "For every dollar I've spent so far, I got back $X on average."

Marginal ROI = Return from the next dollar. "If I spend one more dollar, how much will I get back?"

Key insight: A channel can have high average ROI but low marginal ROI if it's already saturated. For budget decisions, marginal ROI is what matters.

Interactive: Average vs. Marginal ROI

$60K
At $60K spend: Average ROI is 1.82, but Marginal ROI is only 0.75. This means the channel is profitable overall, but the next dollar would lose money. Time to stop growing!

Finding Your Opportunities

3.1 Where Are You on Each Curve?

Understanding your position on each channel's saturation curve reveals opportunities. Channels early on their curves have growth potential; those late are saturated.

Channel Current Spend Saturation Level Position Marginal ROI Recommendation
TV $2.5M 72% Mid-curve 1.15 Limited headroom
Paid Search $1.2M 85% Near saturation 0.65 Consider reducing
Social $0.8M 35% Early curve 2.10 Growth opportunity
Display $0.5M 60% Mid-curve 0.85 Near break-even
Radio $0.3M 25% Early curve 1.85 Growth opportunity

3.2 Marginal ROI Comparison

Comparing marginal ROI across channels shows where the next dollar should go. This is different from which channel has historically performed best!

Reading this chart: Each bar shows the expected return from spending one more dollar on that channel. The red dashed line is break-even (ROI = 1). Channels above the line are still worth investing in; those below are not.

Scenario Planning

4.1 Budget Scenario Planner

Use the sliders below to explore different budget allocations. The model predicts outcomes for each scenario in real-time.

Build Your Scenario

📺 100%
🔍 100%
📱 100%
🖼 100%
📻 100%
Total Spend Change
+0%
Predicted Outcome Change
+0%
Incremental ROI
-

4.2 Pre-Built Scenarios

Click a scenario to see its impact:

🛡
Conservative

Reduce all channels by 20%

-18%
Baseline

Current allocation

+0%
📈
Optimized

Model-recommended mix

+12%
🚀
Aggressive

Increase high-ROI channels

+8%

Practical Guidance

Common Pitfalls

  • Optimizing point estimates: The "optimal" mix has uncertainty. Don't over-rotate on small differences.
  • Ignoring implementation constraints: Can you actually shift budget that fast? Consider operational realities.
  • Assuming stationarity: Saturation curves can shift over time as markets change.
  • Forgetting long-term effects: Brand-building channels may have delayed returns not captured in short-term data.

Best Practices

  • Make changes gradually (10-20% shifts) and measure impact before bigger moves
  • Use scenarios to explore the range of outcomes, not just the "optimal" point
  • Validate with experiments when possible, especially for large reallocation
  • Update saturation curves quarterly as market conditions change

Implementation in MMM Framework

Computing Marginal Contributions

from mmm_framework.analysis import MMMAnalyzer analyzer = MMMAnalyzer(fitted_model) # Compute marginal returns for 10% spend increase marginal_df = analyzer.compute_marginal_contributions( spend_increase_pct=10.0 ) # Output shows which channel benefits most from extra spend: # Channel Current_Spend Increase Marginal_Contribution Marginal_ROAS # Social $800K $80K $168K 2.10 # Radio $300K $30K $55.5K 1.85 # TV $2.5M $250K $287.5K 1.15 # Display $500K $50K $42.5K 0.85 # Search $1.2M $120K $78K 0.65

Running What-If Scenarios

# Test a specific budget reallocation scenario_result = analyzer.what_if_scenario( spend_changes={ 'TV': 1.0, # Keep TV same 'Search': 0.8, # Reduce Search by 20% 'Social': 1.3, # Increase Social by 30% 'Display': 0.9, # Reduce Display by 10% 'Radio': 1.2 # Increase Radio by 20% } ) print(f"Baseline outcome: ${scenario_result.baseline_outcome:,.0f}") print(f"Scenario outcome: ${scenario_result.scenario_outcome:,.0f}") print(f"Change: {scenario_result.outcome_change_pct:+.1%}") # Output: # Baseline outcome: $18,400,000 # Scenario outcome: $19,125,000 # Change: +3.9%

Computing Saturation Curves

from mmm_framework.reporting.helpers import compute_saturation_curves_with_uncertainty # Get saturation curves for all channels curves = compute_saturation_curves_with_uncertainty( model=fitted_model, n_points=100, spend_multiplier=1.5 # Explore up to 150% of current spend ) # Each curve includes: # - spend_levels: Array of spend values # - response_mean: Expected response at each spend level # - response_hdi_low/high: Uncertainty bands # - saturation_level: Current % of maximum response # - marginal_response_at_current: Marginal ROI at current spend for channel, curve in curves.items(): print(f"{channel}: {curve.saturation_level:.0%} saturated") print(f" Marginal response at current: {curve.marginal_response_at_current:.3f}")