Optimisation under uncertainty: planning ad budgets and prices across scenarios

TL;DR

Difficulty: Advanced

Plan for several possible months, not one forecast.

  • Write the uncertainty as scenarios with probabilities and score every plan in every scenario.
  • Ad returns flatten, so the best split gives every channel the same return on its next euro. That shared number is the shadow price of the budget: with your margin, it says whether more budget pays.
  • When stock or capacity caps the upside, planning on the average month overstates the average month.
  • Check the quiet month, not just the average, and set a review date to move money once the month shows its hand.
  • For prices, maximise profit, not revenue: the best price depends on how price sensitive buyers are, not on how big the market is.

Every budget and every price is set before you know how the month will go. In this article I show how to plan across several possible months instead of one forecast, from scenarios and diminishing returns to the shadow price of budget, the flaw of averages and pricing on profit, worked step by step for an invented candle shop in Galway.

A plan built on one forecast is a plan for a month that will not happen

Most budget plans start with a single number. December will bring this much revenue, so we spend this much on ads and set this price. Then December arrives and is either quieter or busier than the number, and the plan was built for neither.

Stochastic optimisation is the name for planning that admits this up front. "Stochastic" just means random. Instead of one forecast you write down several ways the month could go, give each a probability, and choose the budget split or the price that does best across all of them. It sounds like heavy maths. In practice it is a careful spreadsheet with a few honest columns.

I will use one invented business throughout. Claddagh Candles is a small online candle shop in Galway, run by Aoife, selling at claddaghcandles.example. She advertises on Google search and on Meta (Facebook and Instagram). Nobody real, and every number below is made up so I can show every step.

Write the uncertainty down as scenarios with probabilities

The first step is to stop pretending you know the month. A scenario is one complete story of how it could go: quiet, normal or busy, for example. Each gets a probability, and the probabilities add up to 1, because exactly one story comes true. This is the standard way stochastic programming handles uncertainty in practice: formulate scenarios and assign a probability to each.1

Then the goal changes. You no longer ask "what is best if the forecast is right?". You ask "what is best on average across the stories, weighted by how likely each one is?".

max⁡x  ∑k=1Kpk f(x,ωk)subject to∑i=1nxi≤B,xi≥0\max_{x} \; \sum_{k=1}^{K} p_k \, f(x, \omega_k) \quad \text{subject to} \quad \sum_{i=1}^{n} x_i \le B, \quad x_i \ge 0

Here xx is your plan, the list of amounts x1,…,xnx_1, \dots, x_n you spend on each of nn channels. max⁡x\max_{x} means "choose the plan that makes what follows as large as possible". The sum ∑k=1K\sum_{k=1}^{K} runs over the KK scenarios, pkp_k is the probability of scenario kk, ωk\omega_k (the Greek letter omega) stands for everything that is true in scenario kk, and f(x,ωk)f(x, \omega_k) is the profit your plan earns if scenario kk happens. The condition ∑i=1nxi≤B\sum_{i=1}^{n} x_i \le B says the spend on all channels together stays within the budget BB, and xi≥0x_i \ge 0 says you cannot spend a negative amount. The weighted sum is an expected value, explained from scratch in Foundations: expected value, with the probabilities themselves in Foundations: probability.

Worked example: three ways December could go for Aoife

Aoife looks back at three Christmases and talks to her supplier about the market. She settles on three scenarios for December:

ScenarioProbabilityGoogle search doesMeta does
Quiet25%80% of normal50% of normal
Normal50%as normalas normal
Busy25%120% of normal150% of normal

So K=3K = 3, with pquiet=0.25p_{\text{quiet}} = 0.25, pnormal=0.5p_{\text{normal}} = 0.5 and pbusy=0.25p_{\text{busy}} = 0.25. They add up to 1, as they must.

Notice that Meta swings much more than search. That matches what I see in the shops I have worked on: search catches people already looking for candles, so it moves with the season, while social ads depend on a creative landing or flopping, so they swing harder in both directions.

Notice too that the averages work out at exactly normal. For search, 0.25×0.8+0.5×1.0+0.25×1.2=0.2+0.5+0.3=1.00.25 \times 0.8 + 0.5 \times 1.0 + 0.25 \times 1.2 = 0.2 + 0.5 + 0.3 = 1.0. For Meta, 0.25×0.5+0.5×1.0+0.25×1.5=0.125+0.5+0.375=1.00.25 \times 0.5 + 0.5 \times 1.0 + 0.25 \times 1.5 = 0.125 + 0.5 + 0.375 = 1.0. I set it up that way on purpose. Later it lets us compare a plan built on the average month with a plan built on all three, fairly.

Advertising returns flatten as you spend more

Before splitting a budget you need to know what each channel returns at each level of spend. The first euro spent on a channel reaches the people most likely to buy. Each further euro reaches people a little less likely to, so the curve rises fast and then flattens. Google's own researchers describe advertising as having diminishing returns, which plain linear models struggle to capture.2

One simple shape for such a curve is this:

Ri(xi)=ai(1−e−bixi)R_i(x_i) = a_i \left(1 - e^{-b_i x_i}\right)

Here Ri(xi)R_i(x_i) is the revenue channel ii brings in when you spend xix_i on it. The letter aia_i is the ceiling, the most revenue the channel could ever bring however much you spent. The letter ee is the base of the natural logarithm, about 2.718, and e−bixie^{-b_i x_i} starts at 1 when you spend nothing and shrinks towards 0 as spend grows, so 1−e−bixi1 - e^{-b_i x_i} climbs from 0 towards 1. The letter bib_i sets how fast the channel saturates: the larger it is, the sooner the curve flattens. The exponential and the logarithm are explained in Foundations: logarithms.

What matters for decisions is not the height of the curve but its slope: the revenue from the next euro. That is the marginal return.

dRidxi=ai bi e−bixi\frac{dR_i}{dx_i} = a_i \, b_i \, e^{-b_i x_i}

Here dRidxi\frac{dR_i}{dx_i} is the slope of the curve at spend xix_i, the extra revenue one more euro brings, and aia_i, bib_i and e−bixie^{-b_i x_i} are as above. At zero spend the slope is aibia_i b_i, and it falls as spend rises. The difference between the next euro and the average euro is set out in Foundations: marginal versus average.

Worked example: Aoife's two curves

From her past campaigns, Aoife estimates the curves for a normal December. For Google search the ceiling is aS=60,000a_S = 60{,}000 and the saturation rate is bS=0.0002b_S = 0.0002 (one five thousandth). For Meta the ceiling is aM=40,000a_M = 40{,}000 and bM=0.000125b_M = 0.000125 (one eight thousandth).

Spend €5,000 on search: RS=60,000×(1−e−0.0002×5,000)=60,000×(1−e−1)=60,000×(1−0.3679)=37,927R_S = 60{,}000 \times (1 - e^{-0.0002 \times 5{,}000}) = 60{,}000 \times (1 - e^{-1}) = 60{,}000 \times (1 - 0.3679) = 37{,}927. So €37,927 of revenue.

Now the marginal returns on search. At €0, aSbS=60,000×0.0002=12a_S b_S = 60{,}000 \times 0.0002 = 12, so the first euro brings €12. At €5,000 it is 12×e−1=12×0.3679=4.4112 \times e^{-1} = 12 \times 0.3679 = 4.41. At €10,000 it is 12×e−2=12×0.1353=1.6212 \times e^{-2} = 12 \times 0.1353 = 1.62.

On Meta the first euro brings 40,000×0.000125=540{,}000 \times 0.000125 = 5, so €5. At €5,000 it is 5×e−0.625=5×0.5353=2.685 \times e^{-0.625} = 5 \times 0.5353 = 2.68. At €10,000 it is 5×e−1.25=5×0.2865=1.435 \times e^{-1.25} = 5 \times 0.2865 = 1.43.

Revenue against monthly spend, normal DecemberRevenue from Google search and from Meta as monthly spend rises from €0 to €16,000. Both curves rise steeply at first and then flatten, search higher and flattening sooner.Claddagh Candles: revenue by channel and spend€0€25,000€50,000€75,000€100,000€0€4k€8k€12k€16kGoogle searchMetaRevenue in €Monthly spend on the channel

The horizontal axis is what Aoife spends on a channel in a month, from nothing to €16,000. The vertical axis is the revenue that spend brings in a normal December. The takeaway is in the shape: the first €2,000 on search brings almost €20,000, while going from €14,000 to €16,000 adds only about €1,200. The same budget can be well spent or wasted depending on where on the curve it lands.

The best split gives every channel the same next euro

With a fixed budget, the question is how to divide it. The answer is a rule that is easy to say: keep moving money to whichever channel returns more from its next euro, until the next euro returns the same everywhere. If search still paid more than Meta at the margin, shifting a euro from Meta to search would raise revenue, so the split was not yet the best.

The maths behind the rule is the Lagrangian, a way of folding the budget limit into the thing you maximise. At the best plan, every channel's marginal return equals one shared number, written λ\lambda.3

aS bS e−bSxS=aM bM e−bMxM=λ,xS+xM=Ba_S \, b_S \, e^{-b_S x_S} = a_M \, b_M \, e^{-b_M x_M} = \lambda, \qquad x_S + x_M = B

Here xSx_S and xMx_M are the spend on search and on Meta, aSa_S, bSb_S, aMa_M and bMb_M are the curve settings from before, so each side is that channel's marginal return. The Greek letter λ\lambda (lambda) is the shared marginal return both channels end up with, and BB is the total budget. The groundwork is in Foundations: marginal versus average and, for the logarithm used to solve it, Foundations: logarithms.

Worked example: splitting €10,000 for a normal December

Suppose Aoife has €10,000. The rule says 12 e−0.0002xS=5 e−0.000125xM12 \, e^{-0.0002 x_S} = 5 \, e^{-0.000125 x_M} with xM=10,000−xSx_M = 10{,}000 - x_S.

Take the natural logarithm of both sides. The logarithm undoes the ee, so the equation becomes ln⁡12−0.0002 xS=ln⁡5−0.000125 (10,000−xS)\ln 12 - 0.0002 \, x_S = \ln 5 - 0.000125 \, (10{,}000 - x_S).

Put in the numbers: ln⁡12=2.4849\ln 12 = 2.4849 and ln⁡5=1.6094\ln 5 = 1.6094, and 0.000125×10,000=1.250.000125 \times 10{,}000 = 1.25. So 2.4849−0.0002 xS=1.6094−1.25+0.000125 xS2.4849 - 0.0002 \, x_S = 1.6094 - 1.25 + 0.000125 \, x_S.

Gather the xSx_S terms on one side: 2.4849−0.3594=0.000325 xS2.4849 - 0.3594 = 0.000325 \, x_S, so 2.1255=0.000325 xS2.1255 = 0.000325 \, x_S and xS=6,540x_S = 6{,}540. That leaves xM=3,460x_M = 3{,}460.

Check it. On search the next euro returns 12×e−1.308=12×0.2704=3.2412 \times e^{-1.308} = 12 \times 0.2704 = 3.24. On Meta it returns 5×e−0.4325=5×0.6489=3.245 \times e^{-0.4325} = 5 \times 0.6489 = 3.24. Equal, as the rule demands, so λ=3.24\lambda = 3.24.

Revenue at this split is 60,000×(1−0.2704)+40,000×(1−0.6489)=43,778+14,045=57,82360{,}000 \times (1 - 0.2704) + 40{,}000 \times (1 - 0.6489) = 43{,}778 + 14{,}045 = 57{,}823. An even split of €5,000 each brings 37,927+18,590=56,51737{,}927 + 18{,}590 = 56{,}517. Same money, €1,306 more revenue, just from putting it where the next euro works harder.

The shadow price says what more budget is worth

That shared number λ\lambda has a second meaning, and it is the most useful number in the whole exercise. It is the shadow price of the budget: roughly how much the best achievable result rises if you loosen the budget by one euro.3 It answers the question every managing director asks and few dashboards answer: is it worth spending more?

Revenue is not profit, though. To turn the shadow price into a decision, multiply it by the gross margin, the share of each euro of revenue left after the cost of the goods.

extra profit per extra euro=m λ−1\text{extra profit per extra euro} = m \, \lambda - 1

Here mm is the gross margin as a fraction, λ\lambda is the revenue the next euro of budget brings at the best split, so mλm \lambda is the margin it brings, and the 1 is the euro itself. If the result is above zero, more budget pays. The idea is the same one as in Foundations: marginal versus average.

Worked example: should Aoife spend more than €10,000

Aoife's gross margin is 50%, so m=0.5m = 0.5. At €10,000 the shadow price is λ=3.24\lambda = 3.24, so the next euro brings 0.5×3.24−1=1.62−1=0.620.5 \times 3.24 - 1 = 1.62 - 1 = 0.62, a profit of 62 cent. More budget pays.

How far? Until mλ=1m \lambda = 1, so until λ=1/0.5=2\lambda = 1 / 0.5 = 2. On search that happens when 12 e−0.0002xS=212 \, e^{-0.0002 x_S} = 2, so e−0.0002xS=1/6e^{-0.0002 x_S} = 1/6, so xS=ln⁡6/0.0002=1.7918/0.0002=8,959x_S = \ln 6 / 0.0002 = 1.7918 / 0.0002 = 8{,}959. On Meta, 5 e−0.000125xM=25 \, e^{-0.000125 x_M} = 2, so xM=ln⁡2.5/0.000125=0.9163/0.000125=7,330x_M = \ln 2.5 / 0.000125 = 0.9163 / 0.000125 = 7{,}330. Total: €16,289.

At that spend the normal December brings 60,000×(1−1/6)+40,000×(1−0.4)=50,000+24,000=74,00060{,}000 \times (1 - 1/6) + 40{,}000 \times (1 - 0.4) = 50{,}000 + 24{,}000 = 74{,}000 in revenue. And here the plan runs into the real world. Aoife can pour, pack and post at most €65,000 worth of candles in December. Past that, extra orders are refunded or disappoint. The shadow price was right about the curves and wrong about the shop.

Planning on the average month overstates the average month

So Aoife adds the limit: revenue counts only up to €65,000. The natural next move is to plan for the average December, which here is the normal one, and spend until revenue just reaches €65,000. That is the plan almost every business makes. It has a flaw with a name.

Sam Savage called it the flaw of averages: plans based on average conditions usually go wrong.4 The reason is that a limit cuts off the good months but not the bad ones. A busy month cannot sell more than the cap, while a quiet month can fall as far as it likes. Averaging the inputs first and then working out the result is not the same as working out the result in each scenario and then averaging. Whenever there is a cap, a threshold or a curve, the two differ.

The fix is to score every candidate plan in every scenario. The scenario formula from the start does exactly that. The gap between the plan built on all scenarios and the plan built on the average, both scored across all scenarios, is called the value of the stochastic solution.1

profitk=m×min⁡(Rk, C)−B\text{profit}_k = m \times \min\left(R_k, \, C\right) - B

Here profitk\text{profit}_k is the profit after ad spend in scenario kk, mm is the gross margin, RkR_k is the revenue the ads would bring in scenario kk, CC is the capacity limit, min⁡(Rk,C)\min(R_k, C) means "whichever is smaller", so revenue above the limit does not count, and BB is the total ad spend. Each scenario's profit is then weighted by its probability, as in Foundations: expected value.

Worked example: the average plan against the scenario plan

The average plan is €7,500 on search and €5,000 on Meta, €12,500 in all. In a normal December search brings 60,000×(1−e−1.5)=60,000×0.7769=46,61260{,}000 \times (1 - e^{-1.5}) = 60{,}000 \times 0.7769 = 46{,}612 and Meta brings 40,000×(1−e−0.625)=18,59040{,}000 \times (1 - e^{-0.625}) = 18{,}590, a total of €65,202. Capped at €65,000, the profit is 0.5×65,000−12,500=20,0000.5 \times 65{,}000 - 12{,}500 = 20{,}000. That is what the plan promises.

Now score the same plan in each scenario. In a quiet month, search does 80% and Meta 50%: 0.8×46,612+0.5×18,590=37,290+9,295=46,5850.8 \times 46{,}612 + 0.5 \times 18{,}590 = 37{,}290 + 9{,}295 = 46{,}585, so the profit is 0.5×46,585−12,500=10,7920.5 \times 46{,}585 - 12{,}500 = 10{,}792. In a normal month, €20,000 as above. In a busy month the ads would bring €83,819, but the cap holds revenue at €65,000, so the profit is again €20,000.

Weighted: 0.25×10,792+0.5×20,000+0.25×20,000=2,698+10,000+5,000=17,6980.25 \times 10{,}792 + 0.5 \times 20{,}000 + 0.25 \times 20{,}000 = 2{,}698 + 10{,}000 + 5{,}000 = 17{,}698. The plan promised €20,000. Its honest expectation is €17,698. The busy month cannot make up for the quiet one, because the cap took its upside away.

Now the scenario plan. I let a spreadsheet try every split in €100 steps, score each one in all three scenarios and keep the best expected profit. It lands on €7,200 on search and €3,600 on Meta, €10,800 in all. In a normal month that brings 45,784+14,495=60,27945{,}784 + 14{,}495 = 60{,}279, so the profit is 0.5×60,279−10,800=19,3400.5 \times 60{,}279 - 10{,}800 = 19{,}340. In a quiet month, 0.8×45,784+0.5×14,495=36,627+7,247=43,8750.8 \times 45{,}784 + 0.5 \times 14{,}495 = 36{,}627 + 7{,}247 = 43{,}875, profit 21,937−10,800=11,13721{,}937 - 10{,}800 = 11{,}137. In a busy month the cap bites again: 0.5×65,000−10,800=21,7000.5 \times 65{,}000 - 10{,}800 = 21{,}700.

Weighted: 0.25×11,137+0.5×19,340+0.25×21,700=2,784+9,670+5,425=17,8790.25 \times 11{,}137 + 0.5 \times 19{,}340 + 0.25 \times 21{,}700 = 2{,}784 + 9{,}670 + 5{,}425 = 17{,}879.

So the scenario plan spends €1,700 less, earns €181 more on average, and does better in the quiet month. The extra €1,700 of the average plan buys revenue mostly in the busy month, where the cap throws it away.

I want to be honest about the size of this. €181 a month is not a fortune. The bigger gain was the €2,302 gap between what the average plan promised and what it would really deliver. That is the number that stops a business committing to a stock order or a hire on the strength of a profit that was never coming. And without the cap, with only the ceilings uncertain, the average plan would have been exactly right, because the curves scale up and down together. Scenarios earn their keep when something cuts off or bends the outcome: stock, capacity, a minimum order, a contract.

The same average can hide a very different bad month

Expected profit is a long run average. Aoife gets one December a year. Two plans with nearly the same average can leave her in very different places if the quiet month comes, so the next thing to look at is the spread of outcomes. The usual measure is the standard deviation: how far, typically, the result lands from its average.5

σ=∑k=1Kpk(profitk−E[profit])2\sigma = \sqrt{\sum_{k=1}^{K} p_k \left(\text{profit}_k - E[\text{profit}]\right)^2}

Here σ\sigma (sigma) is the standard deviation, pkp_k is the probability of scenario kk, profitk\text{profit}_k is the profit in that scenario, and E[profit]E[\text{profit}] is the expected profit. Each gap from the average is squared so that gaps above and below do not cancel, weighted by its probability, added up, and the square root brings the answer back into euro. The idea is built up in Foundations: spread and Foundations: distributions.

Worked example: three ways to spend €10,800

For the scenario plan, the gaps from €17,879 are 11,137−17,879=−6,74211{,}137 - 17{,}879 = -6{,}742, then 19,340−17,879=1,46119{,}340 - 17{,}879 = 1{,}461, then 21,700−17,879=3,82121{,}700 - 17{,}879 = 3{,}821. Squared: 45,454,564, then 2,134,521, then 14,600,041. Weighted: 0.25×45,454,564+0.5×2,134,521+0.25×14,600,041=11,363,641+1,067,261+3,650,010=16,080,9120.25 \times 45{,}454{,}564 + 0.5 \times 2{,}134{,}521 + 0.25 \times 14{,}600{,}041 = 11{,}363{,}641 + 1{,}067{,}261 + 3{,}650{,}010 = 16{,}080{,}912. The square root is about 4,010, so the standard deviation is about €4,010.

The same steps for two other splits of the same €10,800 give this:

Split (search, Meta)Expected profitQuiet monthStandard deviation
€5,400, €5,400 (even)€17,329€9,958€4,414
€7,200, €3,600 (best average)€17,879€11,137€4,010
€8,400, €2,400 (careful)€17,651€11,319€3,844

The even split is worse on every count, which is worth knowing because it is the split a good few people pick when they have not done the sums. The careful split gives up €228 of expected profit to make the quiet month €182 better and the spread smaller, because search swings less than Meta.

Which to choose is not a maths question. It depends on what a quiet December would do to the business. If €11,137 covers January's rent comfortably, take the higher average. If every euro in the quiet month matters, the careful split is a fair price for sleep. I wrote about weighing that trade in decision theory for founders.

Pricing under uncertainty starts with profit, not revenue

The same thinking applies to prices, with one correction first. A common way to set it up, and the way I once set it up myself, is to maximise expected revenue: price times expected demand. With the usual demand curve that goes nowhere useful.

The usual curve is constant elasticity demand, where a 1% rise in price always cuts demand by the same percentage:

D(p)=α p−βD(p) = \alpha \, p^{-\beta}

Here D(p)D(p) is the number of units sold at price pp, α\alpha (alpha) sets the size of the market, and β\beta (beta) is the price elasticity, how sharply demand falls as price rises. Revenue is then p×αp−β=αp1−βp \times \alpha p^{-\beta} = \alpha p^{1-\beta}. If β\beta is above 1, which most retail products are, revenue rises every time you cut the price, all the way down to giving the product away. Elasticity is explained in Foundations: elasticity.

What you want to maximise is profit, price minus unit cost, times units. Do that and a clean rule falls out, the markup rule from any economics course: the best price sits above cost by a margin that depends only on the elasticity.6

p∗=c×ββ−1p^{*} = c \times \frac{\beta}{\beta - 1}

Here p∗p^{*} is the profit maximising price, cc is the cost of one more unit, and β\beta is the elasticity from before, which must be above 1 for the rule to give an answer. Two things follow. The more price sensitive the customers (the larger β\beta), the closer the price sits to cost. And α\alpha, the size of the market, does not appear at all. The groundwork is in Foundations: elasticity.

That second point matters for uncertainty. If you are unsure only how big December will be, the best price does not move. What moves the best price is uncertainty about how sensitive buyers are.

Worked example: revenue says give it away

Aoife's three candle gift set costs her €12 to make and post. At €24 she expects to sell 1,000 sets, and in a typical year her elasticity is β=2\beta = 2. Revenue at €24 is €24,000. At €20 she would sell 1,000×(20/24)−2=1,000×1.44=1,4401{,}000 \times (20/24)^{-2} = 1{,}000 \times 1.44 = 1{,}440 sets, for €28,800. At €12 she would sell 1,000×22=4,0001{,}000 \times 2^{2} = 4{,}000 sets, for €48,000 of revenue and exactly €0 of profit.

Profit tells the truth. The markup rule gives p∗=12×22−1=24p^{*} = 12 \times \frac{2}{2 - 1} = 24. At €24 the profit is (24−12)×1,000=12,000(24 - 12) \times 1{,}000 = 12{,}000. At €20 it is (20−12)×1,440=11,520(20 - 12) \times 1{,}440 = 11{,}520, lower.

Worked example: pricing when the elasticity is unsure

Aoife is not sure the typical year applies. She writes three scenarios, each selling 1,000 sets at €24: price sensitive buyers (β=3\beta = 3, 25%), typical (β=2\beta = 2, 50%) and loyal (β=1.5\beta = 1.5, 25%). The markup rule gives a different best price in each: 12×3/2=1812 \times 3/2 = 18, then 12×2/1=2412 \times 2/1 = 24, then 12×1.5/0.5=3612 \times 1.5/0.5 = 36.

She can only print one price. So she scores candidate prices in all three, with demand 1,000×(p/24)−β1{,}000 \times (p/24)^{-\beta}.

At €22, 22/24=0.916722/24 = 0.9167. Price sensitive: 0.9167−3=1.2980.9167^{-3} = 1.298, so 1,298 sets and a profit of 10×1,298=12,98310 \times 1{,}298 = 12{,}983. Typical: 0.9167−2=1.1900.9167^{-2} = 1.190, so 1,190 sets and €11,901. Loyal: 0.9167−1.5=1.1390.9167^{-1.5} = 1.139, so 1,139 sets and €11,394. Weighted: 0.25×12,983+0.5×11,901+0.25×11,394=3,246+5,951+2,849=12,0450.25 \times 12{,}983 + 0.5 \times 11{,}901 + 0.25 \times 11{,}394 = 3{,}246 + 5{,}951 + 2{,}849 = 12{,}045.

The same steps at the scenario prices: at €18 the expected profit is €11,199, at €24 it is €12,000, and at €36 it is €10,377. Searching in steps of one cent, the best expected profit, €12,051, sits at €22.48.

Two lessons. First, the profit curve is flat near the top: anything from €22 to €24 earns within about €50 of the best. Second, the damage comes from betting on one extreme scenario. Pricing for loyal buyers at €36 costs €1,674 against the best on average, and pricing for bargain hunters at €18 costs €852. The scenarios do not find a magic price. They stop a confident guess at the edge.

Decide now, correct later

So far Aoife fixes the whole December plan on 1 December. Real budgets are not like that. Ad spend can be moved week by week, and stock can be topped up. Stochastic programming calls this recourse: the ability to take corrective action after a random event has taken place.1 You make the first decision now, see what happens, then make the second with better information. Planning that way is called a two stage problem.

The easiest way to see what recourse is worth is the extreme case. Suppose Aoife knew on 1 December which scenario was coming. She would pick the best plan for that scenario alone. Averaging those best results over the probabilities gives the ceiling: no review process, however clever, can beat knowing the future.

Worked example: what a mid December review could be worth

With the same spreadsheet search, the best plan for each scenario alone is: quiet, €7,800 on search and €1,800 on Meta, for €11,372 of profit. Normal, €7,500 and €4,900, for €20,066. Busy, €5,700 and €2,500, for €24,300, because in a busy month a much smaller spend already fills the €65,000 of capacity.

Weighted: 0.25×11,372+0.5×20,066+0.25×24,300=2,843+10,033+6,075=18,9510.25 \times 11{,}372 + 0.5 \times 20{,}066 + 0.25 \times 24{,}300 = 2{,}843 + 10{,}033 + 6{,}075 = 18{,}951.

The scenario plan earns €17,879. So perfect foresight would be worth at most 18,951−17,879=1,07218{,}951 - 17{,}879 = 1{,}072 a month. That caps what a weekly review is worth. In my experience a review after the first ten days of December recovers a good share of it, mostly by cutting Meta early in a quiet month and cutting both channels once a busy month is clearly on its way to the capacity limit. If a forecasting tool costs more than €1,072 a month for this decision, the arithmetic has already said no.

What this does not do for you

It does not know your curves. Every number above rests on the response curves and the scenario probabilities, and those are estimates. The honest way to get them is past data plus deliberate tests, which I cover in how much data you actually need and, for prices, in modelling demand and price elasticity with regression. Google's own media mix research notes that with small samples the assumptions you start with strongly shape the answer.2

It does not need heavy machinery either. For two or three channels and a handful of scenarios, a spreadsheet that tries every split in sensible steps is enough. Gradient methods and large solvers matter when there are dozens of channels, thousands of scenarios or daily decisions, and a small shop rarely has those.

And it does not remove risk. Aoife can do every step and still have a quiet December. What the method does is put the quiet December on the page before it happens, price it, and stop the plan from quietly assuming it away.

Planning a budget under uncertaintyThe steps from scenarios to a chosen plan: list scenarios with probabilities, estimate the curves, add the hard limits, score every candidate plan in every scenario, check the quiet month, then choose and set a review date.List the scenarios and give each aprobabilityEstimate each channel's response curvein each scenarioAdd the hard limits: budget, stock,capacityScore every candidate plan in everyscenarioIs the quiet month survivable atthe best average plan?yesChoose the plan with the best expectedprofitnoTrade some expected profit for a betterquiet monthSet a review date and move money whenthe month shows its hand

The diagram is the whole method on one page. It starts with the honest list of how the month could go, adds what each channel does and what the shop can physically handle, and only then compares plans, always scored in every scenario rather than in the average one. The decision step is the risk check from the table of three splits, and the last step is the recourse: no plan is final until the month has shown which scenario it is.

Footnotes

  1. NEOS Guide, Stochastic Programming, https://neos-guide.org/guide/types/stochastic/

  2. Yuxue Jin, Yueqing Wang, Yunting Sun, David Chan and Jim Koehler, Bayesian Methods for Media Mix Modeling with Carryover and Shape Effects, Google, 2017, https://research.google/pubs/bayesian-methods-for-media-mix-modeling-with-carryover-and-shape-effects/

  3. Stephen Boyd and Lieven Vandenberghe, Convex Optimization, sections 5.4.4 (price interpretation and shadow prices) and 5.6.3 (local sensitivity analysis), Cambridge University Press, 2004, https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf

  4. Sam Savage, The Flaw of Averages, Harvard Business Review, November 2002, https://hbr.org/2002/11/the-flaw-of-averages

  5. Barbara Illowsky and Susan Dean, Introductory Statistics 2e, section 4.2 Mean or Expected Value and Standard Deviation, OpenStax, Rice University, Houston, 2023, https://openstax.org/books/introductory-statistics-2e/pages/4-2-mean-or-expected-value-and-standard-deviation

  6. Robert S. Pindyck, Lecture Notes on Pricing, 15.013 Industrial Economics for Strategic Decisions, MIT Sloan School of Management, August 2010, https://www.mit.edu/~rpindyck/Courses/Pricing_10.pdf

If you are setting next quarter's budget or prices on a single forecast, bring it to the free workshop and we will put the quiet, normal and busy versions on one page together. The first two weeks of work are on me.