Demand forecasting that cut stockouts by a third

A multi-brand retailer ran on week-old reports and gut feel, leaving shelves empty in some stores and overstocked in others. We unified their sales, inventory, and seasonality data and shipped a forecasting model surfaced in a real-time operations dashboard, turning a guessing game into a planned one.

34%
Fewer stockouts
21%
Lower overstock
Daily
Refresh cadence

What they came with

Ordering decisions were made against reports that were already a week old by the time anyone read them, and the gap between the report and the shelf was filled with judgement. In the same week one store could run out of a line while another sat on it, and neither showed up until the sales figures caught up. Sales, inventory and seasonality each lived in a different system, so producing a single view meant someone exporting and stitching files together by hand.

What the engagement covered

  • Per-SKU, per-store demand forecasts updated daily
  • Anomaly alerts that flag emerging stockout risk early
  • Plain-language insights surfaced to store and ops teams

Technical detail

One grain, one modelled table

Sales, stock movements and calendar effects are landed in Snowflake and modelled in dbt down to a SKU, store and day grain. Forecasting and reporting both read that one table, so the dashboard and the model cannot disagree about what happened.

Daily runs that can be replayed

Airflow orchestrates ingest, feature build and scoring as idempotent tasks partitioned by date. A feed that arrives late re-runs only the partitions it touches instead of forcing a full rebuild of history.

Alerts on residuals, not thresholds

Anomaly detection compares actual sales against the forecast rather than against a fixed reorder level. That catches a line that is still selling but selling faster than planned, which is the case a static threshold misses until the shelf is empty.

The dashboard reads precomputed output

Store and ops views query scored forecast tables rather than calling the model at request time. Page loads stay predictable regardless of how heavy the overnight scoring run was.

The stack

Data

SnowflakedbtAirflow

ML

PyTorchPythonpandas

Application

Next.jsReactTypeScript

Infrastructure

AWSDocker
Practice
Predictive Analytics
Sector
Retail
Shape
Client engagement
Stack
PyTorch, Snowflake, dbt