The problem

The client operates 38 grocery stores. Perishables (produce, bakery, dairy, and prepared foods) are their highest-margin categories and also their biggest source of loss. Store managers ordered using a spreadsheet of trailing averages adjusted by gut feel, which systematically over-ordered before holidays, under-ordered during heat waves, and ignored the effect of the chain's own promotions. Spoilage write-offs were a significant line in the P&L, and out-of-stocks on fresh items were a common customer complaint.

What we actually did

Why not a large language model

This is a tabular forecasting problem with years of structured history, and gradient-boosted decision trees remain one of the strongest, cheapest, and most explainable approaches for it. We benchmarked LightGBM against a seasonal baseline and a deep learning sequence model on a held-out season. The tree model matched the neural model's accuracy at a fraction of the training and serving cost, and buyers could see which features drove each forecast.

Features that reflect how people actually shop

We built daily store-by-SKU features from three years of point-of-sale data: day of week, local holidays and school calendars, the chain's promotion calendar and discount depth, weather forecasts for each store's location, recent sales velocity, and price changes. Weather mattered more than anyone expected: forecast temperature alone explained a large share of variance for salads, cut fruit, and ice cream.

Forecasting the right thing

We trained on sales, but sales are censored by stock-outs: if an item ran out at 3 p.m., the day's sales understate demand. We flagged likely stock-out days from inventory records and treated them differently in training so the model didn't learn to under-forecast popular items. The model outputs a range, not a single number, and order suggestions use a target service level per category that the business chose, higher for staples and lower for items with short shelf life.

A design decision worth calling out
We optimized for the business cost of each error, not raw forecast accuracy. Over-ordering a bakery item costs its full value in waste; under-ordering costs a margin on a lost sale. Encoding that asymmetry per category in the order suggestion mattered more to the P&L than squeezing another point out of the forecast error metric.

Challenges and tradeoffs

Results

After a two-month pilot in eight stores and a phased rollout to all 38, perishable waste fell 23% against the same months of the prior year, adjusted for sales volume. The fresh-item out-of-stock rate improved by 1.6 percentage points at the same time, so the savings didn't come from simply ordering less. The model retrains weekly and is monitored for drift by category and store.

What we'd do differently

We would bring store managers into feature design earlier. Several of the most useful features came from their overrides, and we could have captured that local knowledge before launch instead of after.