Dynamic Pricing for Perishables in a Short Food Supply Chain: When an Algorithm Beats a Fixed Price List
Where algorithmic pricing actually helps a multi-producer food hub, which markdown decisions to automate against declared stock and remaining shelf life, and the three governance rules that stop producers revolting when the platform moves their price.

When does dynamic pricing actually beat a fixed price list?
Dynamic pricing beats a fixed price list in exactly one situation: when the product has a hard expiry and the stock is already committed. If a crate of lettuce is picked, declared and sitting in the hub, its value falls to zero on a known date. A fixed price ignores that clock. A markdown rule does not.
Everything else usually stays fixed. Storable goods like honey, flour, oil, jam and dried herbs have no decay clock, so moving their price only trains shoppers to wait for a discount. Pre-order models where the shopper buys on Monday and the producer harvests on Thursday also have nothing to optimise, because stock is created to match demand rather than sitting at risk. The classic e-commerce case for demand-based pricing, where you raise prices when interest spikes, is the weakest of all in local food: a co-op's shoppers joined partly on a fairness promise, and surge pricing on tomatoes breaks that promise faster than any feature can repair it.
So the honest framing is not "should we do dynamic pricing" but "which of our lines have a decay clock and uncommitted stock". In a typical hub catalogue that is leafy greens, soft fruit, fresh herbs, unpasteurised dairy, bread and prepared items, plus anything returned from a failed delivery. That subset is where an algorithm pays for itself. On the rest, a fixed list is not laziness, it is the correct answer.
- Good fit: picked-and-declared perishables with 1 to 5 days of shelf life, surplus after the order cut-off, undelivered boxes back in the chill room, gluts where one producer declared triple their usual volume.
- Poor fit: shelf-stable pantry goods, made-to-order and pre-harvest items, anything priced by a certification or scheme with a floor, products where a single producer is the only supplier and knows it.
- Never: raising a price above the producer's listed price because demand looks strong.
What the model is actually predicting, and the four inputs it needs
A perishable pricing model does not predict a price. It predicts the probability that a given quantity sells before its expiry at the current price, then solves for the smallest discount that pushes that probability above a threshold. The output is a markdown percentage and a timestamp, not a clever price point.
That reframing matters because it makes the problem tractable on small data. A short food supply chain has hundreds of order lines a week, not millions, so you are not going to learn a smooth demand curve per SKU. What you can learn is much coarser and much more stable: how fast a product category typically clears in the final 24 hours before cut-off, how much a 15 percent versus a 30 percent markdown historically shifted units in that category, and which weeks are structurally slow. A gradient-boosted model on a few thousand rows can do this. So can a well-tuned set of rules, and on a young catalogue the rules usually win.
Four inputs carry nearly all the signal. Declared stock tells you what is at risk, which is why declaration quality upstream sets the ceiling on pricing quality downstream. Remaining shelf life, expressed as hours to the producer's stated best-before rather than a generic category default, gives the urgency. A baseline sell-through rate for the product at list price gives you the counterfactual. And committed demand, meaning baskets already open plus standing subscription lines that will consume stock automatically, tells you how much of the risk is already resolved. Weather, local events and holiday calendars help at the margins, but they are a second-order refinement, not the foundation.
- Declared stock at unit level, per producer, with the declaration timestamp.
- Hours to expiry from a producer-stated best-before, not a category average.
- Baseline sell-through for the product or its category at list price, by day of week.
- Committed demand: open baskets, standing boxes, confirmed restaurant lines.
The markdown ladder: a rules engine you can explain to a 60-year-old grower
Start with a transparent markdown ladder, not a model. A ladder is a small table of time-to-expiry bands mapped to maximum discount percentages, applied only to stock still unsold at each band. It captures most of the available waste reduction, it is auditable line by line, and a producer can predict what will happen to their price before it happens.
A workable ladder for a two-delivery-week hub looks like this. From declaration until 24 hours before cut-off, everything sits at list price, because early discounting just cannibalises full-price sales that were going to happen anyway. At 24 hours before cut-off, unsold units on perishable lines get a modest step, typically 10 to 15 percent, and appear in a clearly labelled section of the storefront. After cut-off, any surplus that has not been allocated to a box moves to a second step, often 25 to 30 percent, and becomes eligible for surplus bundles or add-on offers to shoppers already receiving a delivery on that route. Anything still unsold on the morning of delivery goes to a final tier: donation, staff purchase, or a processing partner who turns it into soup stock or juice, at a price the producer agreed to in advance.
Only once that ladder has run for a full season do you have something worth modelling. At that point you have labelled outcomes, the discount that was applied and whether the unit sold, and you can start replacing fixed percentages with predicted ones. The model's job is narrow: for this category, this day, this quantity, is 12 percent enough, or does it need 22 percent? That is a far safer place to put machine learning than asking it to invent a price from scratch.
The three rules that stop producers revolting when the platform moves their price
Producers revolt over pricing for one reason: the platform changed their number without their consent, and they found out from a shopper. Three rules prevent it. Producers set a floor and opt in per product, discounts are funded by a stated and visible split, and every price change is logged with a reason the producer can read.
Rule one is producer-set floors with per-product opt-in. Each producer declares a list price and a minimum acceptable price, and the algorithm may only move within that corridor. Opt-in is per product, not per account, because a grower will happily discount lettuce and refuse absolutely to discount their specialty cheese. Default everything to opt-out and let producers switch lines on as they see the results. It feels slow and it is the reason the feature survives.
Rule two is a funding split agreed before launch. A discount has to be paid for by someone, and if the answer is always the producer, the feature reads as the co-op protecting its own margin at the grower's expense. The common arrangement is proportional: on a 20 percent markdown, the producer accepts a lower unit price and the co-op accepts a lower commission, in the same ratio as the original split. Whatever the ratio, it belongs in the producer agreement and on the payout statement, so the grower can see both the discount and the co-op's share of it. Rule three is a change log attached to the product: old price, new price, trigger, timestamp, units sold at each tier. Producers do not need to love the algorithm. They need to be able to check it, and to see on Friday that the 18 kilos of chard they would otherwise have composted sold at 24 percent off and returned more than zero.
One practical addition: give producers a manual override with no penalty and no friction. A grower who can pull a product out of the markdown ladder in two taps, at any time, almost never needs to. A grower who has to email an administrator will instead tell the other producers that the platform is discounting their food behind their back.
How to measure whether it worked, and the failure modes to watch
Judge dynamic pricing on three numbers: unsold perishable units as a share of declared stock, average realised price per unit against list, and producer income per declared kilo. Waste falling while realised price stays flat is the win. Waste falling while income per kilo falls is the algorithm simply giving away food.
Run it as a split test rather than a launch. Take two comparable perishable categories, put one on the markdown ladder and leave the other on the fixed list for six to eight delivery weeks, and compare all three metrics. Keep an eye on the interaction effects, because they are where the damage hides. The most common is discount anticipation: a cohort of shoppers learns that Thursday evening brings 15 percent off greens and shifts their whole basket there, so you lose full-price revenue you already had. You detect this by watching the share of perishable units sold at list price over time, and you fix it by making markdowns less predictable in timing and by never discounting a line that cleared fully the previous week.
Two other failure modes deserve a named owner. Cross-producer undercutting happens when two growers list the same product and the ladder marks one down, making the other look expensive for reasons they did not cause; a per-producer opt-in plus a rule that the ladder never discounts a line while a competing line is at list price and has stock removes most of it. And declaration gaming, where a producer inflates declared stock hoping for early exposure, shows up as a widening gap between declared and delivered quantities, which is a data quality problem to fix upstream rather than a pricing problem to fix in the model.
Where this sits in the platform, and what to build first
Dynamic pricing is not a pricing module. It is a thin decision layer sitting on top of three things a short food supply chain platform already needs: accurate declared stock with a timestamp, a per-line shelf-life field, and a payout engine that can apply a discount to both the producer's unit price and the commission. If any of those three is missing, build them before writing a single line of pricing logic.
The build order that works is unglamorous. First, store a best-before or shelf-life-in-days value on every perishable product, entered by the producer during declaration. Second, add price floors and per-product markdown opt-in to the producer app. Third, implement the fixed ladder with a change log and a clearly labelled surplus section on the storefront. Fourth, wire the discount through settlement so payout statements show list price, realised price and who absorbed the difference. Only fifth, after a season of labelled outcomes, replace the fixed percentages with predicted ones. Most hubs capture the majority of the available waste reduction by step three and never need step five.
At Plodie we came to this the same way we came to declaration-based stock, by running Plodovi.hr with a real producer base and watching what happened when the numbers on the storefront stopped matching what a grower expected. The conclusion was not that algorithms are unwelcome in local food. It was that a price is a relationship in a short supply chain, not just a number in a field, and any automation touching it has to be legible to the person whose name is on the product.
Key Takeaways
- Dynamic pricing only pays off on perishables with a hard expiry and already-committed stock; storable and pre-order lines should stay on a fixed price list.
- The model predicts probability of clearing before expiry, then solves for the smallest sufficient markdown. It needs declared stock, hours to expiry, baseline sell-through and committed demand.
- Start with a transparent markdown ladder tied to time-to-cut-off, not a model. Most of the waste reduction is available from rules alone.
- Three rules keep producers on board: producer-set floors with per-product opt-in, a stated and visible discount funding split, and a per-product price change log.
- Measure waste, realised price against list, and income per declared kilo together. Waste falling while income per kilo falls means you are giving food away, not optimising.
Pricing quality is capped by declaration quality, which is why any markdown logic should be built on top of the declaration-based stock model rather than a running inventory the platform has to guess at.
Frequently Asked Questions
Is dynamic pricing legal for food, and do I have to tell shoppers the price changed?
Changing your own list prices over time is generally lawful, but consumer pricing rules in most European jurisdictions require that the price shown is the price charged at checkout, that any advertised discount references a genuine prior price, and that unit pricing is displayed for goods sold by weight. Practically, label markdowns clearly as a surplus or short-shelf-life offer rather than as a limited-time promotion, and never change a price inside an open basket. Check national rules on price-indication and promotional-discount reference periods before launching.
How much data do I need before machine learning beats a fixed markdown ladder?
You need labelled outcomes, meaning records of discount applied and whether the unit sold before expiry, not just sales history. As a rough guide, a season of trading with a few thousand perishable order lines and at least a few hundred marked-down lines per category gives a model something to learn from. Below that, a fixed ladder tuned by an administrator will usually match or beat a model while being far easier to explain.
Should a food hub ever raise prices when demand is high?
Almost never for shopper-facing prices. Surge pricing directly contradicts the fairness positioning most short food supply chains rely on, and it damages trust with both shoppers and producers far more than the extra margin is worth. The legitimate version is producers revising their own list prices between seasons or weeks in response to input costs and scarcity, which is a producer decision rather than an algorithmic one.
What do we do with perishables that still do not sell after the final markdown?
Agree the end of the ladder in writing before you need it. The usual tiers are donation to a food bank or social kitchen, staff and producer purchase at cost, transfer to a processing partner who turns surplus into soup, juice, pickles or stock, and composting as the last resort. Each tier should have an agreed price, including zero, so the producer knows in advance what a final-tier outcome pays them and the co-op can report the volumes in its waste and impact figures.
Does dynamic pricing work for restaurant and wholesale customers as well as households?
It works differently. Chefs buy on availability and consistency more than on price, so a surplus alert with a volume price is more effective than a percentage markdown on the storefront. The practical pattern is a separate surplus notification to wholesale buyers before the household markdown tier opens, since one restaurant taking 15 kilos of chard resolves the risk in a single transaction while retail markdowns clear it a kilo at a time.


