Merchlint
Available now
Next, in this order
  • DeutschDE
  • EspañolES
  • FrançaisFR
  • ItalianoIT
  • PortuguêsPT
  • NederlandsNL
  • SvenskaSV
  • TürkçeTR

A language shows up here once its pages are actually written. Nothing on this site is machine-translated.

Install free
← All checks

Stock that has not sold in a year

Shelves full, order history empty. This stock is money already spent, sitting in a warehouse and counted as an asset while it earns nothing at all.

Group
Money
Confidence
H — heuristic
Version
Pro
Updated
Code
A8

The symptom

Nothing looks wrong. The product is published, priced, photographed and in stock — often in generous quantity. It simply has not been ordered. Not this quarter, not this year.

This is the one check on the list that finds no defect. Every field is correct. The problem is that the catalogue is carrying weight it is not being paid for.

What it costs

Unsold stock is the only kind of catalogue problem where you can name the exact number: quantity on hand multiplied by what you paid for it. That money is spent and cannot be spent again.

  • It is counted as an asset and behaves like a cost. Storage, insurance and stocktaking are charged on it every month it does not move.
  • It hides the products that do sell. Slow items take up the same category listings, the same filter results and the same first page of the shop.
  • The longer it sits, the less it is worth. Seasonal goods, anything with a fashion cycle and anything with a shelf life lose value on a schedule, whether or not anyone is watching.

How to check it yourself

WooCommerce keeps a lookup table of order lines, which makes this a single query rather than a crawl through order meta:

wp db query "SELECT p.ID, p.post_title, sm.meta_value AS stan \
  FROM wp_posts p JOIN wp_postmeta sm ON sm.post_id = p.ID AND sm.meta_key = '_stock' \
  WHERE p.post_type = 'product' AND p.post_status = 'publish' \
  AND CAST(sm.meta_value AS SIGNED) > 0 \
  AND p.ID NOT IN (SELECT product_id FROM wp_wc_order_product_lookup \
                   WHERE date_created > DATE_SUB(NOW(), INTERVAL 12 MONTH))"

Replace wp_ with your table prefix. If wp_wc_order_product_lookup is missing, the analytics tables have never been built — run wp wc tool run regenerate_product_lookup_tables --user=1 first.

Sort the result by quantity, and the top of the list is where the money is.

How to fix it

There is no single fix, because this is a commercial decision rather than a technical one. The useful sequence is:

  1. Check it is unwanted, not unfindable. A product outside every category, hidden from the catalogue or missing a photograph does not sell for reasons that have nothing to do with demand. Rule those out first — they are cheaper to fix than a markdown.
  2. Check the price is not the reason. Compare against what the same product costs elsewhere.
  3. Then choose: discount it, bundle it with something that does sell, move it out of the main catalogue, or write it off. All four are answers; leaving it is not.

When it is a false positive

This check is a heuristic, and it has more legitimate exceptions than any other on the list:

  • Seasonal stock in the wrong half of the year.
  • Spare parts and consumables held deliberately for existing customers, where the point is availability rather than turnover.
  • Safety stock for a product whose main channel is not this store.
  • Products added in the last few months, which have not had a year to sell in.
  • B2B catalogues where one order a year is a normal cadence and a good year.

How Merchlint finds it

Merchlint takes every published product with stock management on and a quantity above zero, then asks the order lookup table whether it appears in any order in the last twelve months. Products added within the window are excluded automatically — they have not had a fair year yet.

The finding is sorted by quantity multiplied by price, so the list starts with the largest amount of money standing still rather than with the largest pile of boxes.

Confidence: H — heuristic. The absence of orders is a fact; calling it a problem is a judgement, and the exceptions above are real. Treat it as a list worth reading, not a list worth acting on line by line.

This check ships in the Pro add-on.

Run this check on your store

Disagrees with what you see in your store? Write to us — we read every message. contact@merchlint.com