Why Your E-commerce Demand Forecast Is Wrong (And How to Fix It)
If your inventory tool uses a 30-day moving average with a seasonal multiplier, it is confidently wrong on roughly a third to half of your catalog. This paper explains why, how to tell, and what to replace it with.
What a forecast is actually for
Before arguing about models, we should be honest about what a demand forecast exists to do. It is not a prediction of the future. It is an input to a reorder decision. You don't care whether your forecast predicts 12 units a week or 14. You care whether the reorder point and order quantity derived from the forecast keep you in stock at your target service level without tying up more capital than you need.
That framing matters because it changes the evaluation. A forecast that is “off by 15% on the mean” but systematically understates variance will cause stockouts. A forecast that looks accurate on the average but gives you false precision will still ruin you when demand spikes. The forecast is a means, not the product.
Why moving averages fail on mixed catalogs
A 30-day moving average computes the mean of the last 30 days of sales and projects it forward. It is simple, cheap to compute, easy to explain, and it's what most inventory tools actually do under the hood. For a SKU that sells 20 units a day with modest noise, a moving average is fine. The mean is a reasonable estimate of tomorrow's demand and the standard deviation of the residuals goes straight into safety stock.
The problem: almost no real e-commerce catalog is that clean.
A typical Shopify + Amazon catalog contains at least four distinct demand shapes, often inside the same product category:
- Fast, steady sellers. 10 to 50 orders a day, low variance. 10 to 20% of SKUs by count, often 50 to 70% of revenue. The industry calls these “smooth.” Moving averages work here.
- Erratic sellers. Similar average volume but high variance. Orders come in bursts. A moving average gets the mean right but understates the variance, so safety stock calculated from the forecast error is too low. Stockouts happen exactly when you thought you had coverage.
- Intermittent sellers. Long gaps between orders. A SKU that sells twice a month has a 30-day moving average of about 0.07 units a day, and most reorder math then proposes buying half a unit, which is nonsense. Tools silently round or fall back to “one unit a week” logic that doesn't match the real distribution.
- Lumpy sellers. Intermittent AND erratic. Two orders in three months, but when an order lands it's for 40 units. Moving averages underreact on reorder quantities and overreact on safety stock for this profile.
On top of the four shapes, there is the data problem: new SKUs with less than 90 days of history, SKUs with missing sales from a broken sync, SKUs where returns have been miscoded as negative sales.
A single model, applied blindly, gets maybe half the catalog right. The other half is where the money is going out the door.
The demand pattern taxonomy
In 2005, Syntetos and Boylan published a simple 2x2 classification the industry still uses. Every SKU is summarized by two numbers:
Average Demand Interval (ADI): the average number of periods between non-zero demand events. A SKU that sells every day has ADI ≈ 1. A SKU that sells twice a week has ADI ≈ 3.5. A SKU that sells once a month has ADI ≈ 30.
Coefficient of Variation Squared (CV²): the variance of demand SIZE (on non-zero days only), divided by the mean squared. A SKU that sells 5 units on every non-zero day has CV² near 0. A SKU where non-zero days span 1 to 40 units has CV² well above 0.5.
The framework splits demand into four classes:
| Class | ADI | CV² | Best-fit model |
|---|---|---|---|
| Smooth | < 1.32 | < 0.49 | Exponential smoothing (ETS) |
| Erratic | < 1.32 | ≥ 0.49 | Damped-trend ETS |
| Intermittent | ≥ 1.32 | < 0.49 | Croston's (or SBA variant) |
| Lumpy | ≥ 1.32 | ≥ 0.49 | Croston's SBA or TSB |
The classification is per-SKU. A catalog that contains a mix of classes needs a mix of models. Applying one model globally is giving up accuracy by convention.
What's actually in the toolbox
Exponential smoothing (ETS, Holt-Winters)
ETS models produce a forecast as a weighted average of past observations, where weights decay exponentially as you go backward in time. Variants handle trend (Holt's method), seasonality (Holt-Winters), and damped trend (which stabilizes long-horizon forecasts by shrinking the trend component over time).
ETS is the best-performing general-purpose method on smooth demand. On erratic demand, damped-trend variants are more robust because they don't overreact to a single high observation.
ETS breaks on intermittent demand. If half the days are zero, the exponentially weighted average is dragged toward zero and the model predicts zero demand across the board. That's obviously wrong for a SKU that sells 12 units a month; the mean is just spread over the right gaps.
Croston's method and its variants
Croston's method, published in 1972, is the simplest method that handles intermittent demand correctly. The trick is separating demand into two processes:
- The size of non-zero demand events, smoothed with exponential weighting.
- The interval between non-zero events, also smoothed.
The forecast is (size / interval), which is the expected demand per period.
The problem with classic Croston's is that it's a biased estimator in edge cases. The SBA variant (Syntetos-Boylan Approximation) corrects the bias with a scaling factor: multiply the size/interval ratio by (1 minus smoothing constant / 2). On most benchmarks, SBA beats vanilla Croston's by a few percent of MASE without any added complexity.
TSB (Teunter-Syntetos-Babai) is another variant that handles demand obsolescence better. If a SKU used to sell once a month and hasn't sold in six months, TSB decays the forecast toward zero instead of holding it constant. Useful when discontinued SKUs linger in the catalog without being explicitly flagged.
Simple moving average (SMA)
SMA is the right answer when you don't have enough history to fit anything else. A 7-day or 30-day SMA has no hyperparameters, is transparent, and degrades gracefully as history thins out. For a SKU launched three weeks ago, no ARIMA or Prophet is going to beat SMA. You're asking a 10-parameter model to predict from 20 observations and it will overfit.
Rule of thumb: if you have less than 90 days of usable history, use SMA and wait. Let the SKU graduate when it has enough data to fit something smarter.
ARIMA, Prophet, and the “dark arts”
ARIMA (Auto-Regressive Integrated Moving Average) is the classic statistical workhorse. In forecasting competitions like M4, ARIMA wins several categories. In production e-commerce, it usually loses. The reason: ARIMA requires parameter tuning per series, and no operator is going to hand-tune (p, d, q) for 5,000 SKUs every week. Auto-ARIMA exists but is slow and picks pathological parameters when data is sparse.
Prophet (the Facebook library) is better tuned to business data. It handles trend + seasonality + holidays + events reasonably out of the box. It performs well on mid-volume, seasonal products. It underperforms Croston's on intermittent demand, and it's opaque enough that operators can't see why it predicted what it did, which is a problem in production when a reorder looks wrong.
LSTM, Transformer-based, and other deep-learning approaches are where the papers are exciting right now. In practice, for the typical e-commerce catalog of 100 to 10,000 SKUs, these models need more data per SKU than you have, and their marginal improvement over a well-chosen classical model is small. They're also expensive to train and opaque to debug. File them under “interesting to watch, rarely the right choice for a small e-commerce operation.”
Seasonal decomposition and event handling
Most catalogs have seasonality. Gift items ramp in November and December. Outdoor products peak May through August. Prime Day is a known event that creates a spike on specific days.
Seasonality is separable from the base demand pattern and should be modeled separately. The standard approach:
- Decompose the raw demand series into trend + seasonal + residual components.
- Model the residual (what's left after removing trend and seasonality) with whichever method matches its demand shape.
- Add the seasonal component back when producing the forecast.
This works because the seasonal multiplier is usually stable year over year, while base demand can drift. A product that became a fast seller over the last 6 months should get ETS on its recent base demand but still use the seasonal multiplier from its historical pattern.
Event handling (Black Friday, Prime Day, new-product launches, promotions) is harder. The cleanest approach is to flag known event days, remove them from the fitting data, fit the base model on “normal” days, and add an event multiplier back for forecast days that are also events. This requires upstream metadata most inventory tools don't collect and most operators don't provide. It's a real gap in the industry.
Data quality: the silent killer
A well-chosen model on bad data is worse than a naive model on good data. The most common e-commerce data quality traps:
- Returns as negative sales. Shopify records a refund as a negative order. If the syncer treats it as a sale, you get minus three units on the return date, pulling the rolling average down. If the syncer treats it as a removal from inventory, the sales history doesn't reflect the return at all and safety stock is overstated.
- Amazon settlement lag. Amazon settles orders 14 days after the order is placed. A demand feed on “orders” is real time; one on “settled orders” is always two weeks behind. Mixing the two silently biases the forecast.
- Pre-order and backorder. An order placed for an out-of-stock SKU is a real demand signal, but most systems either don't record it or record it on the ship date, not the order date. Either way, demand history doesn't match real demand.
- Variant collisions. A SKU listed as three variants on Shopify and one ASIN on Amazon. The unified demand number needs to sum across variants cleanly. If one variant's sync breaks, you undercount.
- Discontinued SKUs. A SKU with 180 days of zero sales because it was delisted, not because demand is intermittent. Should not be forecast at all. Should be flagged and excluded from the pipeline.
- Outliers vs. events. A 3x spike one day. Is that a promotion (real demand, keep it), data error (drop it), or warehouse consolidation (synthetic)? Most tools treat everything above 3x the rolling median as an outlier and drop it, which works for data errors but silently undermines promotional analysis.
A production forecasting system has to handle all of these. Most don't. The ones that do are built by operators who ran into them the hard way.
Uncertainty and service levels
The forecast produces a point estimate (expected demand per day) and a dispersion estimate (standard deviation of the error). Safety stock uses BOTH. The textbook formula:
Safety stock = Z × sqrt(L × σ_demand² + μ_demand² × σ_lead²)Where:
- Z is the service-level z-score (1.65 for 95%, 2.05 for 98%)
- L is the average lead time
- σ_demand is the standard deviation of daily demand
- μ_demand is the average daily demand
- σ_lead is the standard deviation of lead time
Two observations from this formula:
- Safety stock is driven as much by the variance of your forecast as by the mean. A tool that produces a point forecast and hands it to a naive reorder calculator is skipping the variance entirely. That's how stockouts happen even when the reorder point “looks right.”
- Lead time variance is often bigger than demand variance for overseas supply chains. A supplier who quotes 30 days and delivers anywhere between 25 and 60 days contributes more uncertainty than daily demand noise. Safety stock formulas that ignore lead time variance are incomplete.
Good systems report both the point forecast and the error distribution, and feed both into safety stock automatically. The operator sees “reorder point: 340 units at 95% service level” which is the output of the full math, not a projection of the mean alone.
Evaluation: how do you know your forecast is actually good?
The wrong answer is MAPE (Mean Absolute Percentage Error). MAPE is undefined when actual demand is zero, which is exactly when it matters most (intermittent demand). Tools that report MAPE on a mixed catalog are either silently dropping the zero-demand days or reporting infinity. Either way the number is misleading.
The right answer is MASE (Mean Absolute Scaled Error). MASE normalizes your forecast error against a naive baseline: the previous period's observation. A MASE of 1.0 means your forecast is no better than “assume tomorrow equals today.” A MASE of 0.5 means the error is half the naive baseline. A MASE below 1.0 is necessary for a forecast to be worth the compute.
Evaluation should use rolling-origin cross-validation: train on days 1 through 90, predict day 91, then train on days 1 through 91, predict day 92, and so on. Rolling MASE across all predictions is a far more honest measure than fitting once and evaluating on a single held-out period.
Any forecasting tool that can't tell you MASE per SKU is a black box. Any tool that can't surface which SKUs have MASE greater than 1.0 (the forecast is worse than naive) is hiding bad predictions.
Questions to ask any inventory tool
If you're evaluating inventory software, the forecasting questions to ask:
- Do you classify demand patterns per SKU, or apply one model to everything? “One model to everything” means you know the failure modes up front.
- What specific methods do you use for intermittent demand? The answer should include “Croston's,” “SBA,” or similar. “Moving average” or “we handle it automatically” tells you what they're doing.
- How do you handle SKUs with less than 90 days of history? Right answer: “SMA fallback” or “we don't forecast them.” Wrong answer: “we run ETS regardless.”
- How is seasonality handled? Right answer mentions decomposition or seasonal ETS. Wrong answer: “we apply a category-level multiplier,” because category-level doesn't fit SKU-level seasonality.
- Do you score every SKU against a naive baseline, and can I see the ones you are not beating? If the tool cannot separate “we predicted this well” from “this product is easy to predict,” its accuracy number is measuring your catalog rather than its model. Ask us this one too: we score MASE per SKU and surface it as a confidence tier rather than a raw number.
- How is lead time variance incorporated into safety stock? Most tools skip it. If they incorporate it, the math is probably right.
- What happens when my sales history has a known promotional spike? Right answer: “you can flag events and we include or exclude them as configured.” Wrong answer: “our outlier detection handles it,” because a promotion isn't a statistical outlier.
The ReplenishRadar approach
This paper has been mostly about methodology. For completeness, here is what ReplenishRadar does with it:
- Per-SKU classification using the Syntetos-Boylan framework, combined with a data-quality tier (history length, gap ratio, source consistency, recency).
- Model routing per SKU: smooth → ETS, erratic → ETS-damped, intermittent → Croston's SBA, lumpy → Croston's SBA, new or low-history → SMA fallback.
- Seasonal variants engaged when history supports them (two or more years).
- Outlier detection via rolling-median threshold, configurable per catalog.
- Safety stock calculated with full demand variance AND lead time variance.
- MASE scored per SKU against a naive baseline on each run's own evaluation window, surfaced to operators as a confidence tier label. Rolling-origin backtesting is how we evaluate model changes internally; it is not what produces the per-SKU score you see.
The full methodology lives in our demand forecasting feature. The free safety stock calculator and reorder point calculator use the same underlying math so you can sanity-check your own numbers without signing up for anything.
References
- Croston, J. D. (1972). “Forecasting and Stock Control for Intermittent Demands.” Operational Research Quarterly.
- Syntetos, A. A., and Boylan, J. E. (2005). “The accuracy of intermittent demand estimates.” International Journal of Forecasting.
- Teunter, R. H., Syntetos, A. A., and Babai, M. Z. (2011). “Intermittent demand: Linking forecasting to inventory obsolescence.” European Journal of Operational Research.
- Makridakis, S., Spiliotis, E., and Assimakopoulos, V. (2020). “The M4 Competition: 100,000 time series and 61 forecasting methods.” International Journal of Forecasting.
See your own catalog's forecast quality
Doing $5M+ in revenue? Talk to our team