Inventory and supply chain / Decision rules

Critical ratio

The ratio of what a shortage costs to the total cost of both mistakes. It tells you which percentile of demand to stock to, and it is why the right service level differs from SKU to SKU.

Full guide Beginner Interactive: Critical Ratio Explorer →

What problem does this solve?

Every stocking decision under uncertain demand has to answer one question: how much protection against running out is worth paying for? The critical ratio answers it from the economics. It converts two costs, the cost of being one unit short and the cost of being one unit over, into a single probability: the in-stock probability you should aim for.

It replaces a target someone chose by habit (“95% service”) with a target the costs justify.

When should you use it?

  • Setting the stock level, order-up-to level, or reorder point for an item with uncertain demand.
  • Setting different service targets across a catalog, where items have different margins, holding costs, and consequences of a stockout.
  • Sizing any one-shot commitment against an uncertain need: capacity reservations, staffing, spare parts, cash buffers.

It assumes the costs are roughly linear in the number of units short or over. With fixed ordering costs, minimum order quantities, or capacity limits, the critical ratio still sets the target protection, but the order itself also has to respect those structures.

Mathematical formulation

With underage cost cuc_u and overage cost coc_o per unit,

CR  =  cucu+co,F(Q∗)=CR,Q∗=F−1(CR).\text{CR} \;=\; \frac{c_u}{c_u + c_o}, \qquad F(Q^*) = \text{CR}, \qquad Q^* = F^{-1}(\text{CR}).

What goes into each cost depends on the situation.

Situationcuc_ucoc_o
Single period, perishableprice − cost, plus goodwill or penaltycost − salvage
Repeating, leftovers carry over (backorders)backorder penalty bb per unit per periodholding cost hh per unit per period
Repeating, lost saleslost margin p−cp - cholding cost hh per unit per period

For a periodic-review order-up-to policy with backorders, the optimal level is the critical-ratio quantile of demand over the protection interval (lead time plus review period), with CR=b/(b+h)\text{CR} = b / (b + h). For lost sales, (p−c)/(p−c+h)(p - c)/(p - c + h) is the standard approximation.

Intuition

The ratio is a break-even probability. Stock one more unit if it is likely enough to be needed:

P(the next unit is needed)  >  cocu+co  =  1−CR.P(\text{the next unit is needed}) \;>\; \frac{c_o}{c_u + c_o} \;=\; 1 - \text{CR}.

A critical ratio of 0.95 means a unit is worth stocking even if it has only a 5% chance of being used, because a shortage costs 19 times as much as a leftover. A ratio of 0.25 means a unit is worth stocking only if it has at least a 75% chance of being used.

That is why the ratio, not a policy number, should set the service level: the in-stock probability at the optimum is the critical ratio itself.

It also explains a result that surprises people: for low-ratio items, more demand uncertainty means less stock, because the quantile of a wider distribution below the median falls further.

Worked example

Three items, each with forecast demand normal, mean 100, standard deviation 30 per period:

Itemcuc_ucoc_oCRzzStock levelIn-stock probability
Critical spare part$95$10.9902.3116999.0%
Regular item$12$40.7500.6712075.0%
Short-life item$2$60.250−0.678025.0%

A uniform 95% target would hold 149 of each. That under-protects the spare by 20 units, where a shortage is very expensive. It over-stocks the short-life item by 69 units, where most of that extra stock would be thrown away.

Python implementation

from scipy.stats import norm

def critical_ratio(cu, co):
    if cu < 0 or co < 0 or cu + co == 0:
        raise ValueError("costs must be non-negative and not both zero")
    return cu / (cu + co)

items = {
    "critical spare": (95.0, 1.0),
    "regular":        (12.0, 4.0),
    "short-life":     (2.0, 6.0),
}
mu, sigma = 100.0, 30.0
for name, (cu, co) in items.items():
    cr = critical_ratio(cu, co)
    z = norm.ppf(cr)
    level = max(0.0, mu + z * sigma)
    print(f"{name:15s} CR={cr:.3f} z={z:+.2f} stock={level:.0f}")

# Periodic review with backorders: the order-up-to level over lead time L
# plus review period R uses demand over L + R and CR = b / (b + h).
b, h, L, R = 9.0, 1.0, 2, 1
S = mu * (L + R) + norm.ppf(b / (b + h)) * sigma * (L + R) ** 0.5
print(f"order-up-to S = {S:.0f}")

Interactive demonstration

Use the Critical Ratio Explorer to change the two costs and watch the optimal quantity cross the mean as the ratio passes one half. The explainer on order economics shows how the ratio interacts with variability and the planning horizon, and why a weeks-of-cover rule ignores it.

Computational complexity and trade-offs

Computing the ratio is trivial. The work, and the risk, is in the inputs.

  • Cost estimation dominates the error. Underage cost is often understated (goodwill, expediting, downtime), and overage cost is often overstated by using the purchase price instead of holding cost.
  • Distribution choice matters most at extreme ratios, where the answer depends on the tail of the forecast.
  • Sensitivity is easy to check: because only the ratio matters, a 2x error in one cost moves the ratio from, say, 0.75 to 0.86, which is a meaningful but bounded change in the target.

Common mistakes

  • Using one service level for every item. It is optimal only for items whose cost ratio happens to match it.
  • Using purchase price as the overage cost for items that carry over. It makes the ratio far too low.
  • Treating the ratio as a fill-rate target. The ratio is the probability of no stockout in a period; the fill rate, the share of demand served, is usually much higher.
  • Applying the per-period ratio to a single period’s demand when the order has to cover lead time plus review period.
  • Treating the critical ratio as the whole strategy. It is the right answer to “how much protection,” not to how often to order, how to handle minimums, or where in a network to hold stock.