NEW: The Decision Factory — a novel about decisions under uncertainty. Get it on Amazon
Supply Chain · · Adam DeJans Jr.

Sales Are Not Demand

Why observed sales become a censored view of demand during stockouts, and how that mistake can poison forecasts, inventory policies, simulations, and optimization models.

supply-chainforecastinginventoryuncertaintysimulationdecision-science

Sales Are Not Demand

A SKU sells 40 units on Monday, 41 on Tuesday, 39 on Wednesday, and 18 on Thursday.

A forecasting pipeline sees a demand drop.

The business may have seen something completely different: the SKU ran out of inventory at noon on Thursday.

Those 18 units are not evidence that customers wanted 18 units. They are evidence that the business was able to sell 18 units before it stopped being able to observe demand.

This distinction sounds obvious when stated plainly. It is still violated constantly in real supply-chain systems.

The damage is worse than a slightly biased forecast. If observed sales are treated as demand, a stockout can create a feedback loop:

  1. inventory is too low,
  2. sales become constrained by inventory,
  3. the forecasting model interprets low sales as low demand,
  4. the ordering policy buys less,
  5. inventory becomes even lower,
  6. the system becomes increasingly confident in a demand level it helped create.

That is not a forecasting problem in isolation. It is a decision-system problem.

Start with the observation process

Suppose latent customer demand for item (i) in period (t) is

[ D_{it}. ]

Let the inventory available to satisfy that demand be

[ A_{it}. ]

In the simplest lost-sales setting, observed sales are

[ Y_{it} = \min(D_{it}, A_{it}). ]

When (D_{it} < A_{it}), sales reveal demand.

When (D_{it} \ge A_{it}), they do not.

All we know from a clean stockout is

[ D_{it} \ge Y_{it}. ]

The observation is right-censored.

This matters because most forecasting code quietly assumes that the target column is an observation of the thing being predicted. During constrained availability, that assumption is false.

And inventory is only one source of censoring. Demand can also become partially hidden because of:

  • store closures,
  • suppressed assortment visibility,
  • buy-box loss,
  • unavailable sizes or variants,
  • fulfillment restrictions,
  • order caps,
  • website outages,
  • capacity rationing,
  • discontinued listings,
  • substitution to another SKU,
  • rejected orders,
  • long promised delivery dates.

Before fitting a more sophisticated model, ask whether the historical target is actually measuring the phenomenon you think it is measuring.

The first questions I would ask

Before touching a forecast or optimizer, I would want answers to these questions:

  • What exactly is recorded as a sale?
  • Do we know inventory availability at the same grain as demand?
  • Can we identify when an item was unavailable for only part of a period?
  • Are backorders recorded, or does unmet demand disappear?
  • Do customers substitute to another SKU, location, channel, or delivery date?
  • Are canceled orders visible?
  • Does zero inventory mean truly unavailable, or can inventory records lag reality?
  • Are promotions and prices recorded point in time?
  • Does the forecasting dataset preserve what was knowable when the historical decision was made?
  • What action will consume this forecast?

The last question is especially important.

You do not need a philosophical estimate of some unknowable quantity called true demand. You need an uncertainty model good enough to support the decision you actually make.

Lost sales and backorders are different systems

Do not casually use the same inventory equations for both.

In a backorder system, unmet demand may remain observable because the customer order is recorded even though fulfillment happens later. Demand can be represented as something like

[ D_t = S_t + B_t - B_{t-1}, ]

where (S_t) is fulfilled demand and (B_t) is backlog.

In a lost-sales system, the customer leaves. The missing quantity is not directly observed.

That difference changes estimation, simulation, and optimization.

If a model assumes backorders while the business actually loses sales, it can make shortages look cheaper than they are. If it assumes every unit of unavailable inventory represents a lost sale, it can make shortages look much more expensive than they are.

Model the actual customer and fulfillment process.

A practical way to think about the state

For a replenishment problem, I usually want the decision state to distinguish at least:

[ S_t = (I_t, P_t, B_t, F_t, C_t, X_t) ]

where:

  • (I_t): on-hand inventory,
  • (P_t): pipeline inventory by expected arrival,
  • (B_t): backlog, if the business has one,
  • (F_t): demand information available at decision time,
  • (C_t): relevant capacities and supplier constraints,
  • (X_t): availability and commercial state such as price, promotion, assortment, or channel status.

The replenishment action might be

[ x_t = \text{order quantity placed at } t. ]

The policy is then

[ x_t = \pi(S_t; \theta), ]

where (\theta) contains whatever tunable parameters the policy uses.

The demand model is an input to this policy. It is not the final product.

That framing helps because the practical question becomes:

How should we estimate uncertainty from censored observations well enough to choose good actions?

That is a much more useful question than asking for the single correct unconstrained demand number for every historical stockout.

Do not replace every stockout with a made-up point estimate

A common fix is to create an unconstrained_demand column and fill stockout periods with a heuristic estimate.

That can be useful, but it is easy to create false precision.

Suppose 20 units sold before inventory hit zero. The pipeline replaces that with 31.7 estimated units and then treats 31.7 exactly like a real observation during model training.

You have converted uncertainty into fake data.

A better approach is often to preserve the censoring information explicitly.

For a censored observation (Y_t=y), the likelihood contribution is based on

[ P(D_t \ge y), ]

rather than pretending (D_t=y).

Depending on the forecasting method, you can use censored likelihoods, survival-style techniques, latent-demand models, Bayesian models, EM-style estimation, or simulation-based inference.

You do not need the fanciest method available. You do need to stop telling the model that the observed ceiling was the demand.

Partial-period stockouts are especially dangerous

Daily data can hide an important detail.

Imagine a store normally sells throughout a 14-hour day. It sells 30 units by 2 p.m. and then stocks out. The daily sales value is 30.

If you only have end-of-day inventory, you may not know whether the item stocked out at 2 p.m. or 11:55 p.m. Those are very different observations about latent demand.

When possible, preserve:

  • timestamp of stockout,
  • intraday sales curve,
  • inventory snapshots,
  • replenishment receipts,
  • listing availability,
  • channel availability.

At high volume, an intraday exposure model can be more informative than a daily stockout flag.

At lower sophistication, even a field such as fraction_of_period_available is better than pretending all stocked-out days contain equally useful information.

Substitution makes the problem multivariate

Now suppose the customer wanted SKU A, found it unavailable, and bought SKU B.

Observed data contain two distortions:

  • SKU A sales understate its unconstrained demand,
  • SKU B sales may overstate its standalone demand.

If you independently unconstrain A without considering B, you can create demand out of thin air.

This matters in categories with strong substitution: sizes, colors, pack configurations, nearby stores, delivery methods, private-label alternatives, or functionally similar products.

A useful representation may need a choice or substitution model. At minimum, the simulator should not assume that every lost unit from one SKU disappears and every observed unit on another SKU is independent.

The total category economics matter more than preserving a fictional demand identity for each item.

The optimization model needs the right economics

Suppose we choose order quantities (x_{it}). A simplified stochastic objective might be

[ \max_x ; \mathbb{E}\left[ \sum_{i,t} p_i S_{it}

  • c_i x_{it}
  • h_i I_{it}^{+}
  • k_i L_{it} \right], ]

where:

  • (p_i) is contribution from fulfilled demand,
  • (c_i) is acquisition cost,
  • (h_i) is inventory holding or aging cost,
  • (L_{it}) is lost demand,
  • (k_i) captures the economic consequence of a lost unit when that consequence is not already represented by forgone contribution.

A basic lost-sales relationship is

[ S_{it} = \min(D_{it}, A_{it}), ]

[ L_{it} = D_{it} - S_{it}. ]

In a deterministic MILP you may linearize the operating logic differently. In a simulation-based policy, these relationships may simply live in the simulator.

The key is not the exact notation. The key is that the objective is evaluated against plausible latent demand paths, not historical sales paths that were themselves constrained by old inventory decisions.

Otherwise you are benchmarking a new policy against a world in which demand magically falls whenever the old policy stocked out.

This is where historical backtests go wrong

Suppose the old policy stocked out repeatedly during a holiday period. Historical sales were:

[ 100, 100, 100, 43, 0, 0, 0. ]

You replay a new inventory policy against those numbers and proudly conclude that extra inventory would not have helped much. After all, recorded demand went to zero.

But recorded demand went to zero because there was nothing left to sell.

That backtest is structurally incapable of measuring the upside of avoiding the stockout.

This is a classic decision-evaluation trap.

For historical policy evaluation, you need some model of the counterfactual:

What demand might have occurred if inventory had been available?

You will not know that counterfactual perfectly. That is not an excuse to substitute an answer you know is wrong.

Represent the uncertainty.

Forecast accuracy can look better while the decision gets worse

Censoring creates a nasty measurement problem.

A model trained on constrained sales can score well against future constrained sales because the operating policy keeps producing similar censoring.

That does not mean it understands demand.

Imagine two systems:

System A predicts observed sales extremely well but systematically underestimates demand during availability constraints.

System B has slightly worse MAE against recorded sales but produces better latent-demand distributions near stockout conditions.

If the downstream decision is replenishment, System B may generate substantially more profit.

The correct model-selection metric is therefore not just:

[ MAE, RMSE, WAPE, \text{ or bias}. ]

Those are diagnostics.

The stronger test is:

[ \text{out-of-sample economic performance of the resulting policy}. ]

Uncertainty should survive into the decision layer

Unconstraining demand is uncertain by definition.

If an item sold 20 units and stocked out, plausible latent demand might be 21, 30, or 60 depending on the context.

Do not estimate 34 and immediately forget that 34 was uncertain.

Generate scenarios or predictive distributions such as

[ D_t^{(1)}, D_t^{(2)}, \ldots, D_t^{(N)}. ]

Then evaluate the policy across those scenarios.

For each scenario (s), simulate:

  1. starting state,
  2. replenishment decisions,
  3. supplier and transportation behavior,
  4. demand realization,
  5. sales and lost sales,
  6. inventory aging,
  7. future decisions and recourse,
  8. resulting economics.

This is particularly important when lead times are long or orders are discrete. The economic consequence of underestimating latent demand can be highly asymmetric when the next opportunity to recover is months away.

Constraints make censoring more expensive

Suppose an item is ordered in case packs of 24 with an MOQ of 240 units and shares a vendor capacity constraint with 50 other items.

A small change in estimated demand does not necessarily produce a small change in the decision.

It may move the item across a discrete breakpoint:

[ x_i \in {0, 240, 264, 288, \ldots}. ]

Once the order activates, it may consume scarce capacity and displace another SKU.

This is why the value of better demand estimation depends on the downstream decision geometry.

If every plausible demand estimate produces the same order, spending another month improving the unconstraining model may have almost no decision value.

If the item sits near an MOQ, truck, budget, or capacity boundary, a modest improvement can be worth a lot.

Prioritize modeling effort where uncertainty can actually change the action.

A practical implementation pattern

I would separate the production system into four layers.

1. Observation layer

Preserve raw facts rather than immediately manufacturing a corrected target:

  • sales,
  • inventory snapshots,
  • receipts,
  • stockout timestamps,
  • availability flags,
  • prices,
  • promotions,
  • cancellations,
  • backorders,
  • channel state,
  • substitutions where observable.

Never overwrite raw sales with estimated demand.

2. Demand inference layer

Produce a distribution or scenario generator for latent demand conditional on what was observable.

Store model version and data vintage. A historical experiment should be reproducible using only information that existed at that time.

3. Decision layer

Map state and uncertainty into an executable action:

[ x_t = \pi(S_t; \theta). ]

Respect real constraints such as:

  • MOQs,
  • pack sizes,
  • supplier calendars,
  • lead times,
  • capacity,
  • cash budgets,
  • storage limits,
  • transportation constraints,
  • committed orders.

4. Evaluation layer

Replay policies against held-out or simulated demand paths using common scenarios when comparing alternatives.

Measure economics and operational behavior, not only forecast scores.

That separation makes debugging much easier. You can ask whether the problem came from observation, inference, decision logic, or execution rather than staring at one giant pipeline.

Metrics I would actually monitor

For the demand inference layer:

  • censoring rate by SKU/location/time,
  • fraction of volume affected by censoring,
  • calibration on periods where demand is observable,
  • predicted tail behavior around stockouts,
  • bias conditional on availability state,
  • stability across forecast vintages.

For the decision system:

  • contribution margin,
  • lost-margin estimate,
  • holding and aging cost,
  • markdown or disposal cost,
  • order frequency,
  • MOQ activations,
  • capacity utilization,
  • inventory turns as a diagnostic rather than an objective,
  • fill behavior by economically meaningful segment,
  • policy regret against stronger benchmarks where computable.

I would also track decision disagreement between the censored-sales model and the latent-demand model.

If two forecasting approaches disagree numerically but recommend the same action, the disagreement may not matter much.

If they frequently produce different order quantities, those cases deserve investigation.

Failure modes I see repeatedly

Treating zero sales as zero demand

If the item was unavailable, zero sales can contain almost no information about the upper side of demand.

Dropping every stockout period

Removing censored observations avoids one bias but throws away information. Knowing demand was at least 20 is still information.

Filling censored periods with a point estimate and forgetting it was estimated

This creates fake certainty and contaminates model evaluation.

Unconstraining each SKU independently in a substitutable category

You can double count demand and invent category growth that never existed.

Using current corrected history in old backtests

If the corrected series uses information unavailable at the historical decision date, the backtest leaks future information.

Evaluating against historical sales only

This rewards policies that reproduce the consequences of historical stockouts.

Assuming every unavailable unit was a lost sale

The opposite mistake is also common. Availability does not prove a customer would have appeared. Lost demand is latent, not equal to inventory shortage by definition.

Optimizing service metrics without economics

A sophisticated unconstrained-demand model can still feed a bad policy if the objective blindly chases a fill-rate target without pricing excess inventory, obsolescence, capacity, or cash.

A useful experiment before rebuilding anything

You do not need a giant transformation project to find out whether this matters.

Take a representative set of SKUs with meaningful stockout history.

Build three demand treatments:

  1. naive: sales equal demand,
  2. simple correction: a transparent unconstraining heuristic,
  3. probabilistic: a model that explicitly represents censored demand.

Feed all three into the same replenishment policy and simulator.

Use the same uncertainty seeds and operating constraints.

Then compare:

  • order decisions,
  • economic value,
  • stockout frequency,
  • excess inventory,
  • capacity usage,
  • sensitivity near MOQ and other decision boundaries.

If the decisions barely move, congratulations: you have learned that this problem is not currently worth a giant engineering effort.

If the decisions and economics move materially, you now have evidence for where to invest.

That is much better than arguing abstractly about which demand model is more statistically elegant.

The deeper lesson

Supply-chain data are generated by supply-chain decisions.

That sounds trivial, but it changes how you should think about almost every historical dataset.

Sales depend on inventory. Lead-time observations depend on which suppliers you selected. Expedite history depends on old ordering policies. Capacity utilization depends on old allocation decisions. Markdown history depends on old buying decisions.

The data are not a passive recording of nature. They are partly the consequence of the policy that was running when the data were created.

So when a decision system is trained and evaluated on historical data, always ask:

Which parts of this dataset were shaped by the decisions we are now trying to replace?

For inventory, the first place to look is painfully simple.

Sales are what you managed to sell. Demand is what customers wanted. When availability constrained one, do not pretend you observed the other.