Building a dynamic pricing engine for perishables to Reduce Waste & Recover Margins

Building an end-to-end liquidation engine that identifies near-expiry stock automatically, boosts its in-app visibility before touching price, then marks it down dynamically, so the business recovers some margin instead of disposing of it.

~43%

CPO reduction
across markets

~$13k/day

Saved in
Avoided Disposals

~50%

Reduction in Disposal Rate

8 Categories

scaled from FNV to
full Fresh portfolio

ROLE

Senior Business Analyst /
Product Strategy

PROJECT TYPE

Pricing system /
Operational automation

STAKEHOLDERS

Category, Supply Chain,
Dark Store Ops, Pricing

TIMELINE

~ 3 Weeks

TOOLS

Python, SQL,
BI dashboards,
Price elasticity model

MY CONTRIBUTION

Built end-to-end.
Design, code, deployment,
and post-launch across both markets.

What 12 am looked like before this

Every night, low keep life SKUs reach their expiry and are disposed of as a total loss. No secondary channel, no recovery. The loss was a daily certainty, and it compounded with every forecast error that caused an over-order earlier that day.

Identify near-expiry stock automatically, increase in-app visibility to reinforce demand, and re-price the rest to clear excess, without eroding category margin.

The problem

  • No automated trigger of any kind

  • Manual intervention per store, per SKU, every night

  • Expiring SKUs disposed of as a total loss

  • Disposal costs reaching double digits as a percentage of fresh GMV

  • Loss compounds further with every over-order

  • No mechanism to recover category margin

Four levers, pulled in sequence every evening

Each module handles one decision. Together they form a clock-driven sequence from 6 PM to midnight.

COMPONENT 01 · 6 PM

Impression boost first, markdown as backup

At-risk SKUs are surfaced in search and PLP at 6 PM. No price change, no customer-facing markdown signal. Organic demand gets a two-hour window to absorb the excess at full margin.

Recover with visibility first. Markdown only fires if organic demand isn't enough.

COMPONENT 02 · 8 PM

Identifying what to act on, and in which direction

At 8 PM, once the impression boost window closes, every SKU × store combination is evaluated against its live inventory signal. Where stock is tracking below estimated daily sales, a small price uplift is applied. Where stock is in excess, a markdown fires. Both run simultaneously but are not symmetric. The uplift stays deliberately conservative since a price increase risks killing conversion. The markdown goes deeper since clearing expiring stock is the priority.

A - THE DECISION FLOW

HOW THE FNV BACK TRACKING WORKS

Fresh produce carries no on-packet expiry, so the system tracks each inbound batch separately by date. At 8 PM, only units from batches that have reached their keep life today are flagged for liquidation. Units from more recent batches remain in available stock and are excluded.

The eligible quantity is derived by tracing each batch from inbound through sales and disposals to current remaining stock. Units received today with a keep life of 2 or more still have sellable days ahead. They do not enter the liquidation pool.

EXAMPLE

100 units in stock at 8 PM. 50 units received this morning. Keep life intact, excluded from liquidation. 50 units carried over from yesterday's batch. Keep life expiring tonight. Only the 50 carried-over units enter the markdown pool.

B -THE QUANTITY LOGIC

EXPIRING STOCK

All units of SKU × store with last selleable day today

-

EXPECTED NATURAL SALES

All units of SKU × store with last selleable day today

=

LIQUIDATION QTY

All units of SKU × store with last selleable day today

C · THREE INTEGRITY LAYERS IN THE HEATMAP

COMPONENT 03 · 8 PM

Recovering category margin, without the customer noticing

Once the eligibility engine has identified which SKUs are underforecasted, a small price uplift is applied at those SKU × store combinations. Both the uplift and the markdown run simultaneously but are not symmetric. The uplift stays deliberately conservative since a price increase risks killing conversion. The markdown goes deeper since clearing expiring stock is the priority.

GUARDRAILS

COMPONENT 04 · 8 PM

Dynamic markdown depth, not a fixed discount

A price elasticity model calculates the depth needed to move the target liquidation quantity. The greater the excess relative to expected sell-through, the deeper the markdown. Recalculated every hour through midnight.

Guardrails that kept category managers in control

Automation only earns trust when humans can override it cleanly. Four guardrails wrap the entire pipeline.

Why we built a completely separate expected-sale model

A forecast error could no longer silently cause an under-liquidation.

We also consume only a partial share of liquidation units in forward demand forecasts, so the system never starts forecasting for markdown sales. As accuracy improves, this share is designed to shrink automatically.

Disposal down. CPO on target.

Launched in early 2025 with FNV, then expanded to bakery, dairy, milk, meat and seafood, ready-to-go, deli, and flowers. Around 70% of the disposal improvement is attributed to this system, alongside forecasting accuracy gains.

What I'd build next

SNIGDHA NAGPAL
Built at Noon · 2025