How Detection Works (High Level)
What counts as a sale, how days without sale is calculated, and why items are flagged.
Show all sections (18)
- What counts as a "sale"
- What "days without sale" means
- Why detection is variant-level
- Why an item is flagged (the 3 conditions)
- How to verify a flagged item
- Severity badges
- Troubleshooting (symptom-first)
- "This item sold recently — why is it flagged?"
- "I changed threshold but the list didn't update"
- "A variant shows 0 inventory but is still in the dead stock list"
- FAQ
- Should I start with 30, 60, or 90 days?
- Can I change the threshold later?
- Does detection count B2B / wholesale orders?
- Related articles
Detection is built around one question:
"How many days has it been since this item last sold?"
If that number is greater than or equal to your configured threshold (30, 60, or 90 days), the item appears in the dead stock list.
Estimated time: 5 minutes
What you'll accomplish
- Understand how "days without sale" is calculated
- Know what data sources StockSweep uses and why the initial sync matters
- Understand why detection is variant-level (not just product-level)
- Know the top reasons an item is flagged and how to verify
What data detection uses
StockSweep builds its sales history from two sources:
- Initial import — on install, the last 90 days of Shopify order history are imported in batches of 50 orders. This gives detection an immediate baseline.
- Real-time webhooks — after install, StockSweep listens to Shopify
orders/createdandorders/paidevents. Every new qualifying order updates the "last sold" date for the relevant variants automatically.
Both sources feed into the same variant_sales_history table, which stores the most recent qualifying sale date per variant.
When detection runs
- Automatic detection — runs daily at 2:00 AM in your store's timezone. No action needed.
- Manual detection — click "Run Detection" on the Dashboard page at any time.
- After threshold changes — when you change your threshold (30/60/90), StockSweep automatically re-runs detection within 1 hour so results match your new sensitivity.
What counts as a "sale"
A variant is treated as "sold" when it appears as a line item in a qualifying Shopify order. StockSweep processes both orders/created and orders/paid webhook events with idempotent handling (the same order is never counted twice).
Why your numbers might differ from Shopify reports:
| Difference | Explanation |
|---|---|
| Paid vs. created timestamps | Shopify reports may use "order created" date while StockSweep uses "order paid" date, or vice versa. This can shift a sale across day boundaries. |
| Refunds and cancellations | Depending on the metric, refunded or cancelled orders may be excluded from StockSweep's count. |
| Timezone boundaries | A sale at 11:55 PM in one timezone may count as the next day in another. |
| Scope | Shopify reports show store-wide totals. StockSweep only tracks items that meet your dead stock rules. |
For a deep dive, see Numbers don't match Shopify.
What "days without sale" means
For each variant with inventory on hand, StockSweep computes:
Days without sale = today - last qualifying sale date
Then compares that number to your threshold:
| Threshold | Flagged when days without sale is... |
|---|---|
| 30 days | >= 30 |
| 60 days | >= 60 |
| 90 days | >= 90 |
If a variant has never sold (no qualifying orders found in the imported history or via webhooks), it is treated as having an infinite "days without sale" and is flagged regardless of threshold.
Why detection is variant-level
Shopify products can have multiple variants (size, color, material), and each variant sells at a different rate. For example:
- "T-Shirt / Small / Black" might sell weekly
- "T-Shirt / XXL / Yellow" might not have sold in 120 days
Product-level detection would miss this distinction. Variant-level detection lets you:
- Target discounts precisely to the variants that are not moving
- Keep selling variants untouched
- Get accurate frozen capital calculations per variant (inventory quantity x cost)
The Dead Stock Table displays variant-level rows by default, with columns for product name, variant title, days without sale, inventory on hand, inventory value, and last sale date.
Why an item is flagged (the 3 conditions)
An item appears in the dead stock list when all three conditions are true:
- Days without sale >= threshold — the variant has not sold within your configured window
- Inventory on hand > 0 — there is physical stock to act on (sold-out items are not flagged)
- Not excluded — the variant has not been manually excluded/archived from the dead stock list
How to verify a flagged item
- Open the variant in the Dead Stock Table and note the last sale date and days without sale
- Open the same product in Shopify Admin → Orders and search for the most recent order containing that variant
- Compare the order date to the "last sale date" shown in StockSweep
- Confirm the difference between today and that date exceeds your threshold
If the dates don't match, check the common differences table above (paid vs. created timestamps, refunds, timezone).
Severity badges
Items in the dead stock list are color-coded by age for fast visual triage:
| Badge | Days without sale | Meaning |
|---|---|---|
| Yellow | 30–59 days | Early warning — monitor, consider merchandising tweaks |
| Orange | 60–89 days | Likely dead stock — start discount testing |
| Red | 90+ days | High confidence dead stock — strongest clearance candidates |
These badges appear in both the Dead Stock Table and the Aging Bucket chart on the Dashboard.
Troubleshooting (symptom-first)
"This item sold recently — why is it flagged?"
Likely cause: StockSweep and Shopify use different timestamps (paid vs. created), or the recent order was refunded/cancelled. Fix: open the variant in StockSweep and compare the "last sale date" to the actual order in Shopify. Check if the order status is paid (not just created) and not refunded. How to confirm: the last sale date in StockSweep matches the most recent qualifying (paid, non-refunded) order in Shopify.
"I changed threshold but the list didn't update"
Likely cause: re-detection is still running (it triggers within 1 hour of a threshold change). Fix: wait up to 1 hour, then refresh. Check System Status for the last detection run timestamp. How to confirm: "last detection run" timestamp updates and dead stock counts change to reflect the new threshold.
"A variant shows 0 inventory but is still in the dead stock list"
Likely cause: inventory was updated in Shopify after the last detection run, but detection has not re-run yet. Fix: run detection manually or wait for the next daily auto-run at 2:00 AM. How to confirm: after the next detection run, the variant is removed from the list.
FAQ
Should I start with 30, 60, or 90 days?
- 60 days — best default for most stores. Catches meaningful dead stock without too much noise.
- 30 days — if you have high velocity (daily sales across most SKUs) and want earlier intervention.
- 90 days — if you sell seasonal, long-tail, or made-to-order inventory where 60 days is normal.
Can I change the threshold later?
Yes, at any time. Changing threshold triggers automatic re-detection within 1 hour. Your Discount History and past actions are not affected.
Does detection count B2B / wholesale orders?
StockSweep processes all Shopify orders that trigger orders/created and orders/paid webhooks. If your B2B orders flow through the same Shopify store, they count as sales.
Related articles
Was this article helpful?
Let us know — your feedback helps us improve our documentation.