Holt-Winters, explained for people who run kitchens

Holt-Winters is a way of describing a sales history as three separate things that add up: the level (roughly how much you sell), the trend (which way that is moving), and the seasonality (what each particular month does to it). It updates all three every time a new month closes, weighting recent months more heavily than old ones. That is the whole idea. Everything else is the arithmetic of how much more heavily.

Most demand forecasting software runs on some version of this method, including StocksSense. It is sixty years old, it is public, and it has no machine learning in it whatsoever — which is the main reason it is worth understanding rather than trusting. A method you can check is a method you can argue with when it is wrong.

The three components

Level — where the line sits

The level is the current baseline: strip out the direction of travel and the calendar, and this is what a normal month looks like right now. Not the average of the last year — the estimate of where things stand today, which is a different number the moment demand has moved at all.

The important word is “current”. A plain average treats a month from last September as exactly as informative as last month. Holt-Winters does not: each new month nudges the level toward what just happened, by an amount set by a smoothing factor usually written as alpha. A high alpha makes the forecast twitchy — it chases every good week. A low alpha makes it stubborn — it takes months to notice that the new menu is selling. Fitting the model means choosing that dial, and the trade-off is real in both directions.

Trend — which way it is going

The trend is how much the level moves per month, and it gets its own smoothing factor. In a kitchen this is the slow stuff: word of mouth building, a delivery platform ramping up, a competitor opening across the street. It is the component most hand-methods ignore entirely, and it is usually the cheapest accuracy you can buy — projecting a level that is drifting upward as if it were flat means under-ordering by a bit more every single month, in the same direction, forever.

Seasonality — what this month always does

Seasonality is a repeating multiplier attached to each position in the cycle. For monthly restaurant data the cycle is twelve, so there are twelve of them: January might carry 0.83 and December 1.17, meaning January runs 17% under the line and December 17% over — every year, for reasons that have nothing to do with whether the business is doing well.

This is the component that stops a forecast from confusing weather with performance. Without it, a strong summer reads as growth and the model orders as though it will continue into November.

What each component contributes, on one ingredient
ComponentAnswersGets it wrong when
LevelWhat is a normal month right now?Demand shifted suddenly and the dial is set too slow to notice
TrendWhich way is normal moving?A one-off spike is read as the start of a climb
SeasonalityWhat does this month of the year do?There is under a year of history, so the pattern is guesswork

Additive or multiplicative

There are two versions, and the difference matters more than the jargon suggests. Additive seasonality says December adds thirty portions. Multiplicative says December multiplies by 1.17.

For a restaurant that is growing, multiplicative is almost always right. If your December bump is genuinely a bump of a fixed thirty portions, then as the business doubles, December becomes proportionally less special — which is not how a busy month behaves. A December that is 17% busier stays 17% busier at any size. Get this wrong on a growing business and the seasonal correction quietly shrinks relative to the trend, year over year.

How much history it needs, and why

A seasonal pattern cannot be estimated until the calendar has repeated. With eleven months, there is no arithmetic in existence that can distinguish “December is always busy” from “last December, one thing happened”. Twelve months is the absolute floor and it is a weak floor; two full years is where the seasonal estimate starts being worth much.

StocksSense handles this by falling back to a simpler trend-only model (Holt, without the Winters part) when there is not enough history to justify a seasonal pattern, and by capping the confidence it will claim for a product that has one cycle of history or less. Both are refusals rather than features, which is what makes them worth mentioning — the alternative is a number that flatters everybody.

Measuring whether it is any good

There are two ways to score a forecast and only one of them means anything.

The wrong way is to fit the model on all your history and then measure how closely it matches that same history. This is a self-graded exam. The model has seen every answer, and a sufficiently flexible model will score perfectly on the data it was fitted to while being useless on the next month.

The right way is one-step-ahead error: walk forward through the history, and at each month, predict it using only the months before it — then compare. Those are genuine predictions of things the model had not seen. Average how far off they were, and you have a number that can actually get worse when the model is doing badly, which is the entire point of a confidence score. StocksSense scores this way, which is why a product’s reliability rating can fall.

That per-product error is also what a safety-stock buffer should be sized from. An item whose forecasts have historically been within 5% needs far less padding than one that has been off by 30%, and applying the same percentage to both over-orders the first and leaves the second short. Reliability-weighted buffers are just this observation, applied per item, every cycle.

What it cannot see

This is the part most vendors skip, and it is the part you need in order to use a forecast well. Holt-Winters extrapolates the patterns in your sales history. It therefore cannot see anything that is not in your sales history.

  • A road closure, a festival, or a competitor opening or closing — none of which have happened in your numbers yet.
  • Weather, unless you feed it in separately. A heat wave changes what people order and no amount of past-sales arithmetic anticipates it.
  • A menu change. Rename or reformulate an item and the history attached to the old name is describing a different product.
  • The reason behind a number. It sees that you sold 40 fewer portions in January; it cannot see that you were closed for four days.
  • Anything that has never happened before. This is not a flaw to be engineered around — it is what extrapolation means.

So the correct use of a demand forecast is as a well-informed default that you override with things you know and it does not. StocksSense layers a weather and local-events adjustment on top of the statistical baseline for paid accounts, but that layer is a limited adjustment to the forecast, not a replacement for it — months of sales history outweigh a forecast of rain, and should.

Why explain any of this

Because the honest answer to “how does your forecasting work” is a method with a name, a public specification, and known failure modes — not “AI”. A kitchen that understands why the number moved can tell when the number is wrong, and a kitchen that cannot will either follow a bad order guide off a cliff or stop using it entirely the first time it misses.

If you would rather see the arithmetic than read about it, the companion article works the entire chain by hand on a single ingredient: average, trend, seasonality, buffer, and where each step changes the order.