Demand Forecasting
Overview
Demand forecasting uses historical sales data, seasonal patterns, and lead times to predict how much inventory you'll need and when to reorder. Chronic stockouts or overstock situations are usually a sign that reorder points are based on intuition rather than data. Purpose-built inventory planning tools handle this for most merchants — custom forecasting code is only necessary for unique operational requirements.
When to Use This Skill
- When chronic stockouts or overstock situations indicate that current reorder points are set incorrectly
- When building automated replenishment recommendations to reduce manual inventory review
- When planning inventory for seasonal peaks (Black Friday, back-to-school, holiday season)
- When you have 12+ months of sales history and want to extract meaningful demand patterns
- When integrating with supplier lead times and purchase order workflows for end-to-end replenishment
Core Instructions
Step 1: Determine your platform and choose the right forecasting tool
| Platform |
Recommended Tool |
Why |
| Shopify |
Inventory Planner (Shopify App Store) or Cogsy |
Inventory Planner connects directly to Shopify, analyzes 12+ months of sales history, calculates reorder points, and generates purchase orders |
| WooCommerce |
ATUM Inventory Management (free/premium) or Inventory Planner |
ATUM provides reorder point management natively in WooCommerce; Inventory Planner has a WooCommerce connector for advanced forecasting |
| BigCommerce |
Inventory Planner or Linnworks |
Both have BigCommerce native integrations and handle multi-location inventory forecasting |
| Multi-channel |
Skubana (now Extensiv) or Linnworks |
Handles inventory forecasting across Shopify, WooCommerce, Amazon, and eBay from a single dashboard |
| Custom / Headless |
Build a time-series analysis layer on top of your order database |
Use moving averages, seasonal decomposition, and safety stock formulas against your historical sales data |
Step 2: Set up sales history data collection
Accurate forecasting requires clean historical data. Before running any forecast:
- Ensure cancelled and refunded orders are excluded from your sales totals — most forecasting tools handle this automatically when connected to your platform
- Tag promotional periods — flash sales, holiday spikes, and influencer-driven demand should be flagged as abnormal; they inflate baseline demand estimates if included uncritically
- You need at least 6 months of history for basic seasonal pattern detection; 12+ months is required to see year-over-year trends
Shopify
Using Inventory Planner:
- Install Inventory Planner from the Shopify App Store (14-day free trial, then $99+/month)
- Inventory Planner pulls your full Shopify sales history automatically on connection
- Connect your suppliers in Inventory Planner → Suppliers with their lead times (e.g., Supplier A = 14 days, Supplier B = 7 days)
- Set your desired service level (e.g., 95% — meaning you want to have stock for 95% of demand scenarios) in Settings → Forecasting
- Inventory Planner calculates reorder points and recommended order quantities per SKU, updated daily
Shopify Analytics (built-in, no app needed for basic trends):
- Go to Analytics → Reports → Inventory
- The "Days of inventory remaining" report shows how many days of stock you have at current sell-through rate
- Go to Analytics → Reports → Sales over time → group by product to see monthly sales trends
- Use these as inputs for manual reorder decisions if you don't want to pay for a forecasting app
WooCommerce
Using ATUM Inventory Management (free tier available):
- Install ATUM Inventory Management for WooCommerce from WordPress.org (free) or purchase the premium version
- ATUM adds a master inventory list view with real-time stock levels, daily sales rates, and low-stock alerts
- In ATUM → Settings → Reorder Points, configure your reorder levels and safety stock per SKU
- ATUM's premium Purchase Orders module generates POs automatically when stock hits the reorder point
Using Inventory Planner for WooCommerce:
- Connect Inventory Planner to WooCommerce via their native API connector
- Same workflow as Shopify — Inventory Planner analyzes your WooCommerce sales history and generates forecasts
BigCommerce
Using Inventory Planner:
- Connect Inventory Planner via the BigCommerce API (Inventory Planner → Settings → Connect Store)
- Inventory Planner pulls sales history from BigCommerce and generates replenishment recommendations
BigCommerce built-in low-stock alerts:
- Go to Products → [Product] → Inventory
- Set "Low stock level" for each product — BigCommerce emails you when stock drops below this threshold
- This is a simple alert, not a forecast — use it as a backstop while you set up a proper forecasting tool
Step 3: Configure reorder points and safety stock
Reorder point = demand during lead time + safety stock buffer.
In Inventory Planner:
- Inventory Planner calculates this automatically based on your sales history and supplier lead times
- Review the recommendations in Inventory Planner → Replenishment — items are sorted by urgency (days of stock remaining vs. lead time)
- Adjust recommendations manually before creating purchase orders (e.g., if you know a supplier has extra lead time for a specific product)
- Export purchase orders directly from Inventory Planner to email to your suppliers
Manual calculation (if not using a forecasting tool):
- Average daily demand = total units sold in last 30 days / 30
- Safety stock = (maximum daily demand – average daily demand) × lead time in days
- Reorder point = (average daily demand × lead time in days) + safety stock
- Example: Average daily demand = 5 units, lead time = 14 days, max daily demand = 8 units
- Safety stock = (8–5) × 14 = 42 units
- Reorder point = (5 × 14) + 42 = 112 units
Step 4: Plan for seasonal demand
Seasonality is the biggest cause of forecast errors. Plan for it explicitly.
In Inventory Planner:
- Go to Inventory Planner → Settings → Seasonality
- Inventory Planner detects seasonal patterns automatically from your sales history
- For first-year merchants (no prior year data): manually set seasonal multipliers — e.g., December = 3x normal demand for holiday products
Building a seasonal calendar manually:
- Export your sales by month for the past 2+ years from Shopify Reports / WooCommerce / BigCommerce
- Calculate the ratio of each month's sales to the annual average (December / average month = seasonal index)
- Apply the seasonal index to your daily demand forecast when placing orders for the upcoming peak season
Promotional calendar:
- Flag planned promotions (flash sales, influencer campaigns) in your forecasting tool
- Most forecasting tools allow manual demand overrides for specific date ranges
- For Black Friday/Cyber Monday: increase your forecast by your historical BFCM lift percentage (typically 3–8x for e-commerce)
Step 5: Generate and approve replenishment recommendations
In Inventory Planner:
- Go to Inventory Planner → Replenishment → Review recommendations
- Filter by "Critical" (stock-out in fewer days than lead time) and "Warning" (stock-out within 2x lead time)
- Adjust quantities if you have market intelligence the model doesn't know (planned sales, anticipated supply issues)
- Click "Create Purchase Order" — Inventory Planner generates a PO to send to your supplier
- Track the PO status in Inventory Planner → Purchase Orders; when received, update actual receipt dates to improve future lead time estimates
Step 6: Custom / Headless — demand forecasting from sales data
// Compute average daily demand from your order database
async function computeAverageDailyDemand(
productId: string,
lookbackDays: number = 30
): Promise<number> {
const since = new Date();
since.setDate(since.getDate() - lookbackDays);
const result = await db.raw(`
SELECT COALESCE(SUM(ol.quantity), 0) AS total_units
FROM order_lines ol
JOIN orders o ON o.id = ol.order_id
WHERE ol.product_id = ?
AND o.status NOT IN ('cancelled', 'refunded')
AND o.created_at >= ?
`, [productId, since]);
return result.rows[0].total_units / lookbackDays;
}
// Calculate reorder point with safety stock
function calculateReorderPoint(params: {
avgDailyDemand: number;
maxDailyDemand: number; // observed peak daily demand
leadTimeDays: number;
}): number {
const safetyStock = (params.maxDailyDemand - params.avgDailyDemand) * params.leadTimeDays;
return Math.ceil(params.avgDailyDemand * params.leadTimeDays + safetyStock);
}
// Generate replenishment recommendations for all active products
async function generateReplenishmentReport(): Promise<{
productId: string;
sku: string;
currentStock: number;
reorderPoint: number;
daysOfSupply: number;
urgency: 'critical' | 'warning' | 'ok';
}[]> {
const products = await db.products.findAll({ is_active: true, track_inventory: true });
const recommendations = [];
for (const product of products) {
const inventory = await db.inventory.findByProductId(product.id);
const avgDemand = await computeAverageDailyDemand(product.id, 30);
const maxDemand = await computeAverageDailyDemand(product.id, 7); // shorter window = more volatile
const leadTimeDays = product.supplier_lead_time_days ?? 14;
const reorderPoint = calculateReorderPoint({ avgDailyDemand: avgDemand, maxDailyDemand: maxDemand, leadTimeDays });
const daysOfSupply = avgDemand > 0 ? Math.floor(inventory.quantity_on_hand / avgDemand) : 999;
const urgency = daysOfSupply < leadTimeDays ? 'critical' : daysOfSupply < leadTimeDays * 2 ? 'warning' : 'ok';
if (urgency !== 'ok') {
recommendations.push({ productId: product.id, sku: product.sku, currentStock: inventory.quantity_on_hand, reorderPoint, daysOfSupply, urgency });
}
}
return recommendations.sort((a, b) => a.daysOfSupply - b.daysOfSupply);
}
Best Practices
- Start with a tool like Inventory Planner before building custom forecasting — $100–$300/month is far cheaper than engineering time, and the models are more accurate than a hand-rolled moving average
- Set a minimum of 6 months of sales history before trusting any forecast; for new products, use a category-average demand rate as a proxy
- Adjust forecasts for known events — planned promotions, seasonal campaigns, and supply chain disruptions should be entered as manual overrides in your forecasting tool
- Track forecast accuracy monthly — compare forecast units to actual units sold; if you're off by more than 25% consistently, recalibrate your assumptions or look for a structural change in demand patterns
- Account for pending purchase orders — subtract quantity on order from your recommended replenishment qty before placing a new PO; double-ordering is a common and expensive mistake
Common Pitfalls
| Problem |
Solution |
| New products have no history to forecast from |
Use category average demand rate for the first 90 days; Inventory Planner has a "new product" mode that adjusts for this |
| Forecast doesn't account for supplier stockouts |
Track supplier fill rates in your vendor management system; if a supplier consistently ships 80% of ordered qty, order 25% more to compensate |
| Safety stock too low, stockouts still happen |
Increase your service level setting in Inventory Planner from 90% to 95–98% for high-velocity SKUs |
| Replenishment recommendation ignores open POs |
Always check "quantity on order" before creating a new PO; Inventory Planner shows this automatically, but manual calculations often miss it |
Related Skills
- @order-management-system
- @vendor-management
- @multi-channel-selling
1---2name: demand-forecasting3description: Predict future inventory needs using historical sales data, seasonal trends, and reorder points to prevent stockouts and overstock4---56# Demand Forecasting78## Overview910Demand forecasting uses historical sales data, seasonal patterns, and lead times to predict how much inventory you'll need and when to reorder. Chronic stockouts or overstock situations are usually a sign that reorder points are based on intuition rather than data. Purpose-built inventory planning tools handle this for most merchants — custom forecasting code is only necessary for unique operational requirements.1112## When to Use This Skill1314- When chronic stockouts or overstock situations indicate that current reorder points are set incorrectly15- When building automated replenishment recommendations to reduce manual inventory review16- When planning inventory for seasonal peaks (Black Friday, back-to-school, holiday season)17- When you have 12+ months of sales history and want to extract meaningful demand patterns18- When integrating with supplier lead times and purchase order workflows for end-to-end replenishment1920## Core Instructions2122### Step 1: Determine your platform and choose the right forecasting tool2324| Platform | Recommended Tool | Why |25|----------|-----------------|-----|26| **Shopify** | Inventory Planner (Shopify App Store) or Cogsy | Inventory Planner connects directly to Shopify, analyzes 12+ months of sales history, calculates reorder points, and generates purchase orders |27| **WooCommerce** | ATUM Inventory Management (free/premium) or Inventory Planner | ATUM provides reorder point management natively in WooCommerce; Inventory Planner has a WooCommerce connector for advanced forecasting |28| **BigCommerce** | Inventory Planner or Linnworks | Both have BigCommerce native integrations and handle multi-location inventory forecasting |29| **Multi-channel** | Skubana (now Extensiv) or Linnworks | Handles inventory forecasting across Shopify, WooCommerce, Amazon, and eBay from a single dashboard |30| **Custom / Headless** | Build a time-series analysis layer on top of your order database | Use moving averages, seasonal decomposition, and safety stock formulas against your historical sales data |3132### Step 2: Set up sales history data collection3334Accurate forecasting requires clean historical data. Before running any forecast:35361. **Ensure cancelled and refunded orders are excluded** from your sales totals — most forecasting tools handle this automatically when connected to your platform372. **Tag promotional periods** — flash sales, holiday spikes, and influencer-driven demand should be flagged as abnormal; they inflate baseline demand estimates if included uncritically383. **You need at least 6 months of history** for basic seasonal pattern detection; 12+ months is required to see year-over-year trends3940#### Shopify4142**Using Inventory Planner:**431. Install **Inventory Planner** from the Shopify App Store (14-day free trial, then $99+/month)442. Inventory Planner pulls your full Shopify sales history automatically on connection453. Connect your suppliers in Inventory Planner → Suppliers with their lead times (e.g., Supplier A = 14 days, Supplier B = 7 days)464. Set your desired service level (e.g., 95% — meaning you want to have stock for 95% of demand scenarios) in Settings → Forecasting475. Inventory Planner calculates reorder points and recommended order quantities per SKU, updated daily4849**Shopify Analytics (built-in, no app needed for basic trends):**501. Go to **Analytics → Reports → Inventory**512. The "Days of inventory remaining" report shows how many days of stock you have at current sell-through rate523. Go to **Analytics → Reports → Sales over time** → group by product to see monthly sales trends534. Use these as inputs for manual reorder decisions if you don't want to pay for a forecasting app5455#### WooCommerce5657**Using ATUM Inventory Management (free tier available):**581. Install **ATUM Inventory Management for WooCommerce** from WordPress.org (free) or purchase the premium version592. ATUM adds a master inventory list view with real-time stock levels, daily sales rates, and low-stock alerts603. In ATUM → Settings → Reorder Points, configure your reorder levels and safety stock per SKU614. ATUM's premium **Purchase Orders** module generates POs automatically when stock hits the reorder point6263**Using Inventory Planner for WooCommerce:**641. Connect Inventory Planner to WooCommerce via their native API connector652. Same workflow as Shopify — Inventory Planner analyzes your WooCommerce sales history and generates forecasts6667#### BigCommerce6869**Using Inventory Planner:**701. Connect Inventory Planner via the BigCommerce API (Inventory Planner → Settings → Connect Store)712. Inventory Planner pulls sales history from BigCommerce and generates replenishment recommendations7273**BigCommerce built-in low-stock alerts:**741. Go to **Products → [Product] → Inventory**752. Set "Low stock level" for each product — BigCommerce emails you when stock drops below this threshold763. This is a simple alert, not a forecast — use it as a backstop while you set up a proper forecasting tool7778### Step 3: Configure reorder points and safety stock7980Reorder point = demand during lead time + safety stock buffer.8182**In Inventory Planner:**831. Inventory Planner calculates this automatically based on your sales history and supplier lead times842. Review the recommendations in Inventory Planner → Replenishment — items are sorted by urgency (days of stock remaining vs. lead time)853. Adjust recommendations manually before creating purchase orders (e.g., if you know a supplier has extra lead time for a specific product)864. Export purchase orders directly from Inventory Planner to email to your suppliers8788**Manual calculation (if not using a forecasting tool):**89- **Average daily demand** = total units sold in last 30 days / 3090- **Safety stock** = (maximum daily demand – average daily demand) × lead time in days91- **Reorder point** = (average daily demand × lead time in days) + safety stock92- **Example:** Average daily demand = 5 units, lead time = 14 days, max daily demand = 8 units93 - Safety stock = (8–5) × 14 = 42 units94 - Reorder point = (5 × 14) + 42 = 112 units9596### Step 4: Plan for seasonal demand9798Seasonality is the biggest cause of forecast errors. Plan for it explicitly.99100**In Inventory Planner:**1011. Go to Inventory Planner → Settings → Seasonality1022. Inventory Planner detects seasonal patterns automatically from your sales history1033. For first-year merchants (no prior year data): manually set seasonal multipliers — e.g., December = 3x normal demand for holiday products104105**Building a seasonal calendar manually:**1061. Export your sales by month for the past 2+ years from Shopify Reports / WooCommerce / BigCommerce1072. Calculate the ratio of each month's sales to the annual average (December / average month = seasonal index)1083. Apply the seasonal index to your daily demand forecast when placing orders for the upcoming peak season109110**Promotional calendar:**111- Flag planned promotions (flash sales, influencer campaigns) in your forecasting tool112- Most forecasting tools allow manual demand overrides for specific date ranges113- For Black Friday/Cyber Monday: increase your forecast by your historical BFCM lift percentage (typically 3–8x for e-commerce)114115### Step 5: Generate and approve replenishment recommendations116117**In Inventory Planner:**1181. Go to Inventory Planner → Replenishment → Review recommendations1192. Filter by "Critical" (stock-out in fewer days than lead time) and "Warning" (stock-out within 2x lead time)1203. Adjust quantities if you have market intelligence the model doesn't know (planned sales, anticipated supply issues)1214. Click "Create Purchase Order" — Inventory Planner generates a PO to send to your supplier1225. Track the PO status in Inventory Planner → Purchase Orders; when received, update actual receipt dates to improve future lead time estimates123124### Step 6: Custom / Headless — demand forecasting from sales data125126```typescript127// Compute average daily demand from your order database128async function computeAverageDailyDemand(129 productId: string,130 lookbackDays: number = 30131): Promise<number> {132 const since = new Date();133 since.setDate(since.getDate() - lookbackDays);134135 const result = await db.raw(`136 SELECT COALESCE(SUM(ol.quantity), 0) AS total_units137 FROM order_lines ol138 JOIN orders o ON o.id = ol.order_id139 WHERE ol.product_id = ?140 AND o.status NOT IN ('cancelled', 'refunded')141 AND o.created_at >= ?142 `, [productId, since]);143144 return result.rows[0].total_units / lookbackDays;145}146147// Calculate reorder point with safety stock148function calculateReorderPoint(params: {149 avgDailyDemand: number;150 maxDailyDemand: number; // observed peak daily demand151 leadTimeDays: number;152}): number {153 const safetyStock = (params.maxDailyDemand - params.avgDailyDemand) * params.leadTimeDays;154 return Math.ceil(params.avgDailyDemand * params.leadTimeDays + safetyStock);155}156157// Generate replenishment recommendations for all active products158async function generateReplenishmentReport(): Promise<{159 productId: string;160 sku: string;161 currentStock: number;162 reorderPoint: number;163 daysOfSupply: number;164 urgency: 'critical' | 'warning' | 'ok';165}[]> {166 const products = await db.products.findAll({ is_active: true, track_inventory: true });167 const recommendations = [];168169 for (const product of products) {170 const inventory = await db.inventory.findByProductId(product.id);171 const avgDemand = await computeAverageDailyDemand(product.id, 30);172 const maxDemand = await computeAverageDailyDemand(product.id, 7); // shorter window = more volatile173 const leadTimeDays = product.supplier_lead_time_days ?? 14;174175 const reorderPoint = calculateReorderPoint({ avgDailyDemand: avgDemand, maxDailyDemand: maxDemand, leadTimeDays });176 const daysOfSupply = avgDemand > 0 ? Math.floor(inventory.quantity_on_hand / avgDemand) : 999;177 const urgency = daysOfSupply < leadTimeDays ? 'critical' : daysOfSupply < leadTimeDays * 2 ? 'warning' : 'ok';178179 if (urgency !== 'ok') {180 recommendations.push({ productId: product.id, sku: product.sku, currentStock: inventory.quantity_on_hand, reorderPoint, daysOfSupply, urgency });181 }182 }183184 return recommendations.sort((a, b) => a.daysOfSupply - b.daysOfSupply);185}186```187188## Best Practices189190- **Start with a tool like Inventory Planner before building custom forecasting** — $100–$300/month is far cheaper than engineering time, and the models are more accurate than a hand-rolled moving average191- **Set a minimum of 6 months of sales history** before trusting any forecast; for new products, use a category-average demand rate as a proxy192- **Adjust forecasts for known events** — planned promotions, seasonal campaigns, and supply chain disruptions should be entered as manual overrides in your forecasting tool193- **Track forecast accuracy monthly** — compare forecast units to actual units sold; if you're off by more than 25% consistently, recalibrate your assumptions or look for a structural change in demand patterns194- **Account for pending purchase orders** — subtract quantity on order from your recommended replenishment qty before placing a new PO; double-ordering is a common and expensive mistake195196## Common Pitfalls197198| Problem | Solution |199|---------|----------|200| New products have no history to forecast from | Use category average demand rate for the first 90 days; Inventory Planner has a "new product" mode that adjusts for this |201| Forecast doesn't account for supplier stockouts | Track supplier fill rates in your vendor management system; if a supplier consistently ships 80% of ordered qty, order 25% more to compensate |202| Safety stock too low, stockouts still happen | Increase your service level setting in Inventory Planner from 90% to 95–98% for high-velocity SKUs |203| Replenishment recommendation ignores open POs | Always check "quantity on order" before creating a new PO; Inventory Planner shows this automatically, but manual calculations often miss it |204205## Related Skills206207- @order-management-system208- @vendor-management209- @multi-channel-selling