An inventory aging report sorts every SKU on hand by days since its last sale and totals the cost in each bucket. Running one takes seven steps: pick a window, export stock and costs, pull sales, join on SKU, bucket, classify and rank. The output shows which cash is healthy, slow-moving, overstocked or dead.
I think of the aging report as roll call for the back room. Every carton back there answers with a recent sale or stays silent. The silent ones are holding part of your rent, payroll and next season's buy.
This guide gives exact report names and menu paths for Shopify, Square and Lightspeed Retail X-Series. I checked each against the platform's help center on October 15, 2026. A worked example follows, built on an illustrative store, so you can check your math against mine.
What You Need Before You Start an Inventory Aging Report
An aging report needs four inputs, and missing any one of them skews every bucket. Gather these before you open a spreadsheet:
- A full catalog export with on-hand units for every SKU, including items that have never sold.
- A unit cost for every SKU. Average cost is fine, but fill blank costs from supplier invoices first.
- Unit sales by SKU for at least the last 180 days, from every channel you sell through.
- Receiving dates, or at least a list of what arrived in the last 60 days, so new stock doesn't get misfiled.
Two terms carry through every step. A SKU's age here means days since its last sale.
Days of cover means units on hand divided by average units sold per day. It's how long current stock lasts at the current pace.
The report ends by sorting every SKU into four classes. These are the starting rules I use:
- Healthy: sold in the last 60 days, with 90 days of cover or less.
- Overstock: sold in the last 60 days, with more than 90 days of cover. The item sells, and the store bought too many.
- Slow-moving: last sale between 61 and 180 days ago. It still sells, but below the rate that justifies its shelf space and the cash it holds.
- Dead stock: in stock and available for the whole window, with no sale in the last 180 days.
Those thresholds are starting points. A furniture store with long sales cycles might stretch them, and a candy shop might halve them. Pick yours, write them down and keep them fixed between runs.
For a directional number before you build the sheet, start with the free trapped-cash estimate, then come back for the SKU work. This directional questionnaire gives a benchmark range; use a supported connection or reviewed item-level upload for SKU-level analysis.
The 7 Steps to Run an Inventory Aging Report
Each step below names the report to pull on each platform. A worked figure from the illustrative gift shop, described in full later, closes each step.
Step 1: Set the Snapshot Date, the Lookback Window and the Aging Clock
Write down the snapshot date and the lookback window before you export anything. Every report you pull has to use those same dates, or the totals won't reconcile later.
Then pick the clock. Age can run from the last sale or from the last receipt, and each answers a different question.
Square's Aging inventory report runs on the receipt clock. It shows the weighted average number of days items have been in stock, plus a Last Received Date for each item.
Key insight
Classify eligible SKUs by days since their last sale, and use receipt dates only to protect new arrivals. Time on the shelf shows how long stock has waited. Time since the last sale shows whether customers still want it.
Worked figure: snapshot date October 1, 2026. Lookback window April 4 to October 1, 2026, which is 180 days.
Step 2: Export Every SKU With On-Hand Units and Unit Cost
Pull the full catalog first, including SKUs that never sold. Shopify's Products by sell-through rate and Products by percentage sold reports leave out variants with no sales, per Shopify's inventory reports documentation. Neither can be your starting list.
- Shopify: go to Products > Inventory, click Export, choose All locations and All states, then click Export inventory. The All states file includes an On hand (current) column for each location. For cost, go to Products > Export; the product CSV carries a Cost per item column.
- Square: in the Item library, click Actions > Export Library, per Square's inventory tracking guide. Unit costs are a Plus or Premium feature in Square for Retail. On other plans, add costs from supplier invoices.
- Lightspeed Retail X-Series: go to Reporting > Inventory Reports. Inventory on Hand covers products with stock, while All Inventory Levels includes products with none. The report's figures include Current Stock, Inventory Cost and Item Value, which Lightspeed defines as average cost per item.
Worked figure: 1,180 SKUs with stock on hand. Thirty-seven had a blank cost, which the owner filled from invoices before moving on. Total on hand came to $96,400 at cost.
Step 3: Pull Unit Sales by SKU for Four Date Windows
Run your sales-by-SKU report four times, once per age window. Each SKU's age bucket is the most recent window where it shows a sale, which gets you last-sale recency from standard reports.
- Shopify: go to Analytics > Reports, click the Category filter and choose Sales. Open Total sales by product variant, which shows the Variant SKU. The Inventory category also has Inventory sold daily by product, which gives average units sold per day for each variant.
- Square: go to Reports > Custom > Custom Item report and set the date range. Click Export for a CSV or Excel file, per Square's item sales guide. Retail Plus and Premium also offer Inventory Sell-through under Inventory Reports, with sell-through rate and sales velocity columns.
- Lightspeed Retail X-Series: go to Reporting > Inventory Reports, click the Performance tab and select Product as the Report Type. With the Date Range set to All Time, a blank Items Sold column marks a product that has never sold.
| Age window (days since last sale) | Date range for the illustrative store |
|---|---|
| 0 to 30 | September 1 to October 1, 2026 |
| 31 to 60 | August 2 to August 31, 2026 |
| 61 to 90 | July 3 to August 1, 2026 |
| 91 to 180 | April 4 to July 2, 2026 |
The first three windows together cover the last 90 days. Add them up per SKU and you have the sales figure for days of cover, with no fifth export needed.
Step 4: Join Stock, Cost and Sales on SKU
Put the catalog in one tab and each sales window in its own tab. Then use XLOOKUP on SKU to bring units sold into the catalog. Wrap each lookup so a missing match returns "MISSING" instead of zero.
Add a days-of-cover column with this formula: =OnHand/(Sold90/90). Leave it blank where 90-day sales are zero, since those SKUs get classified by recency in step 6.
Every SKU that fails to match goes on an exceptions list. Changed SKUs, blank SKUs and variants merged during a catalog cleanup are the usual causes.
Worked figure: 1,151 of 1,180 rows matched on the first pass. The 29 misses were 17 blank SKUs and 12 renamed ones, all fixed by hand.
A candle with 18 on hand and 45 sold in 90 days shows 36 days of cover. A ceramic mug with 48 on hand and 24 sold shows 180.
Step 5: Assign Each SKU an Age Bucket and Value It at Cost
Give every SKU one age bucket based on its most recent window with a sale. SKUs with no sale in any window go in the over-180 bucket.
Multiply on-hand units by unit cost for each SKU, then sum by bucket with a pivot table. Use cost, because cost is the cash you already spent.
| Days since last sale | SKUs | Value at cost |
|---|---|---|
| 0 to 30 | 610 | $41,200 |
| 31 to 60 | 175 | $12,300 |
| 61 to 90 | 120 | $9,800 |
| 91 to 180 | 140 | $14,600 |
| Over 180, or no sale in the window | 135 | $18,500 |
| Total | 1,180 | $96,400 |
Step 6: Classify Each SKU as Healthy, Slow-Moving, Overstock or Dead Stock
Apply your written thresholds to every row with a formula, so no SKU gets sorted by feel. Then pull out the false positives before any dollar total goes on the wall.
Four kinds of SKU can look dead or slow before they've had a fair chance to sell:
- New arrivals received inside the last 60 days.
- Items that were out of stock for much of the window, so they had nothing to sell.
- Seasonal lines being held for their season.
- SKUs that sold through a channel your export missed, such as wholesale or a market stall.
Put these on a review list with a recheck date. They stay out of the four classes until that date.
Worked figure: 135 SKUs had no sale in 180 days. Of those, 22 arrived in the last 60 days and 9 were holiday lines.
Those 31 SKUs, worth $5,500 at cost, went to review. That left 104 dead-stock SKUs worth $13,000.
Step 7: Rank Each Class by Dollars and Assign a First Action
Sort each class by value at cost, largest first, and give the top rows an owner and a date. Ranking by dollars puts your attention where the cash sits, and the cash rarely sits where the unit count is highest.
Slow-moving SKUs usually start with a planned markdown sequence, and these markdown tactics cover the options. Overstock calls for pausing reorders until cover falls back under your threshold.
Dead stock needs a harder call between markdown and liquidation, and this comparison of markdown and liquidation lays out the tradeoffs. If a write-down comes up, talk to your accountant.
Worked figure: the 20 largest dead-stock SKUs held $6,900 of the $13,000. The owner assigned all 20 a first action within a week.
A Worked Example End to End: One Illustrative Gift Shop
This store is an illustration. Its numbers are invented to show the math, and they don't describe any real retailer or CMP client.
Take a hypothetical 1,400-square-foot gift and home goods shop on Shopify. It carries 1,180 SKUs with stock on hand, worth $96,400 at cost. Monthly sales run about $40,000, and rent is $6,800 a month.
The owner ran the seven steps above with an October 1, 2026 snapshot and a 180-day window. Days of cover split the 785 SKUs that sold in the last 60 days. The 64 carrying more than 90 days became overstock.
| Class | SKUs | Value at cost | Share of inventory value |
|---|---|---|---|
| Healthy | 721 | $43,800 | 45.4% |
| Overstock | 64 | $9,700 | 10.1% |
| Slow-moving | 260 | $24,400 | 25.3% |
| Dead stock | 104 | $13,000 | 13.5% |
| Held for review | 31 | $5,500 | 5.7% |
| Total | 1,180 | $96,400 | 100% |
Slow-moving covers both the 61 to 90 bucket and the 91 to 180 bucket: 260 SKUs worth $24,400. Healthy and overstock together match the 785 SKUs and $53,500 that sold in the last 60 days.
The dead stock alone is $13,000, or about 1.9 months of this shop's rent. Add the slow movers and the total reaches $37,400, about 5.5 months of rent sitting in the back room.
Store example
In this illustrative gift shop, 104 dead-stock SKUs hold $13,000 at cost, close to two months of rent. See your own number by SKU in a free workspace: connect Shopify, Square or an eligible Lightspeed store, or upload a spreadsheet. Direct availability depends on production launch status and workspace eligibility; compatible item-level exports remain available after column review.
The shop's inventory of $96,400 against roughly $40,000 in monthly sales gives an inventories-to-sales ratio of about 2.4. That ratio is a blunt instrument, but it's a useful one to put next to the national figure.
Key data point
U.S. retailers outside motor vehicles and parts held 1.09 months of sales in inventory at the end of July 2026. That's the preliminary, seasonally adjusted ratio in the Census Bureau's September 16, 2026 release. It blends every retail category, so use it as context only.
The owner's first moves came straight from the ranking:
- A markdown schedule for the 40 largest slow movers.
- Reorder holds on all 64 overstock SKUs.
- A liquidation quote on the top 20 dead-stock lines.
Common Mistakes at Each Step of an Inventory Aging Analysis
Most broken aging reports fail at a specific step, and each failure has a plain fix.
| Step | Common mistake | Fix |
|---|---|---|
| 1. Window and clock | Changing the window between runs, or mixing the receipt clock with the sale clock | Write the dates and the clock at the top of the sheet and reuse them |
| 2. Catalog export | Starting from a sell-through report that drops never-sold variants | Start from the full inventory or item library export |
| 3. Sales windows | Leaving out sales from wholesale, events or a second register system | Add every channel's unit sales before the join |
| 4. Join | Letting failed lookups count as zero sales | Flag misses as "MISSING" and clear the exceptions list |
| 5. Buckets and value | Valuing stock at retail price, which inflates every bucket | Value at unit cost or average cost |
| 6. Classification | Calling new arrivals and seasonal lines dead | Move them to a review list with a recheck date |
| 7. Ranking | Ranking by units, or treating cost value as cash you'll get back | Rank by value at cost, and price recovery separately |
Operator tip
Starting October 1, 2026, Shopify's inventory reports measure On hand quantity instead of Available quantity, per Shopify's help center. Compare a new aging run with an older one and you may see quantity shifts that have nothing to do with sales.
How to Check Your Work Before You Act on the Report
Reconcile the aging sheet against your point-of-sale totals before you mark down a single item. These five checks catch most of the errors that matter:
- Total value at cost should land close to your system's own figure. That's Month-end inventory value in Shopify, Inventory Cost in Lightspeed, or Inventory Value in Square's Aging inventory report.
- The four classes plus the review list should add up to your catalog's SKU count, with no SKU in two places. A COUNTIF on SKU finds duplicates.
- The exceptions list from step 4 should be empty.
- Pull ten dead-stock SKUs at random and find them on the shelf or in the back room. If three are missing, your counts need work before your buckets do.
- Check the five healthy SKUs with the highest days of cover. If any sit above your threshold, the formula has a bug.
A small gap between your sheet and the system total is normal. Shopify's Month-end inventory value, for one, only counts products with a cost per item. A large gap means missing costs or a bad join.
Where Cash Margin Partners Fits in an Aging Review
Cash Margin Partners is an inventory cash-recovery practice for independent, owner-operated retailers. It shows them exactly how much cash is trapped in unsold inventory and gives them a prioritized plan to get it back.
CMP runs the steps above automatically from a read-only connection. Shopify and Square Point of Sale connect directly, and the integrations page lists what each one reads.
Lightspeed Retail X-Series connects through a capacity-managed custom app that may pause new connections, so availability depends on workspace eligibility. Any other system works through a CSV, TSV or Excel upload with a guided column review.
The CMP diagnostic classifies eligible SKUs as dead stock, slow mover, overstock, stockout risk, healthy active or data incomplete. Where there's enough supported sales history and cost data, CMP estimates 30, 60 and 90-day cash-at-risk. Forecasts and predictive alerts require a recent successful supported live connection and sufficient history and cost evidence; model projections are not guarantees.
The limitation is the same one your spreadsheet has: thin or messy cost and sales data produces thin analysis. If you'd rather compare software before deciding, see the 7 best inventory aging report tools for retail.
Frequently Asked Questions About Inventory Aging Reports
What is an inventory aging report?
An inventory aging report groups every SKU on hand by days since its last sale and totals the cost in each group. It shows how much cash sits in stock that has stopped moving, and which SKUs to act on first.
How often should I run an inventory aging report?
Run an inventory aging report at least once a quarter, and always before a major buying decision. Keep the window, clock and thresholds the same each time, so you can see whether the dead-stock total is shrinking.
What age buckets should an aged inventory report use?
An aged inventory report works well with five buckets, counted in days since last sale. Use 0 to 30, 31 to 60, 61 to 90, 91 to 180, and over 180. Stretch the buckets for slow-turning categories like furniture and tighten them for fast-turning ones like snacks or cards.
What's the difference between slow-moving inventory and overstock?
Slow-moving inventory still sells, but its last sale was 61 to 180 days ago, too slow for the shelf space it holds. Overstock sold recently, but the store holds more than 90 days of cover. Slow movers need demand, and overstock needs fewer reorders.
Do Shopify, Square and Lightspeed have a built-in inventory aging report?
Square has an Aging inventory report under Reports > Inventory for Square for Retail Plus and Premium subscribers. Shopify's published list of default inventory reports includes no aging report. Lightspeed Retail X-Series users can find never-sold products in the Performance tab of Inventory Reports.
Is the cost value in an aging report the cash I'll get back?
Value at cost measures cash already spent on the stock, which is different from what you'll get back. Recovery depends on markdown prices, liquidation offers and buyer demand for the category. For dead stock, it often comes in below cost.
Start Here: Your First Inventory Aging Report This Week
- Today, export your catalog with on-hand units and count how many SKUs have a blank cost.
- Write down your snapshot date, a 180-day window and your four class thresholds.
- Run your sales-by-SKU report for the four age windows.
- Build the join and the pivot, then reconcile the total to your system's inventory value.
- Assign a first action to the 20 largest dead-stock SKUs before the week is out.
To skip the spreadsheet, connect your store or upload your exports to a free workspace. You'll see your trapped-cash figure by SKU. It's free, with no card and no time limit.
