What Happens When Your Shopify Inventory Goes Out of Sync?
When Shopify inventory goes out of sync with the warehouse, the store either sells units that are not on the shelf or shows items as sold out while they sit in a bin. The cause is usually one of two things: a floor event such as a receipt, return, damage or transfer that never reached Shopify, or two systems writing the same number over each other. Shopify's inventory adjustment history shows which, before anyone recounts.
Shopify says you have 14. The bin has 9. Or the reverse: the product page says sold out, and a picker walks past a full bin of it every morning.
When Shopify inventory goes out of sync with the warehouse, one of two things happens. Either the store sells units that are not on the shelf, and someone has to cancel an order, or it hides units that are, and the sales simply never happen. Nobody gets an error for the second one.
Two causes come up again and again. A movement happened on the floor and was never recorded correctly in Shopify: a receipt, a return, a damaged unit, a mis-pick, a transfer. Or two systems wrote the same number, and one overwrote the other. They need different fixes, and Shopify's own adjustment history often narrows down which one you have before anyone recounts a bin.
What does "out of sync" actually mean in Shopify?
Shopify tracks more than one number per item per location, and comparing the wrong one with your shelf creates a gap that is not real. Its Help Center defines the states this way:
- Available: "inventory that you can sell."
- Committed: "units that are set aside and can't be sold, such as units in an unfulfilled order, reserved in a draft order, or in a transfer that's marked as ready to ship."
- Unavailable: "units set aside by apps or held for other reasons, such as damaged, quality control, or safety stock."
- Incoming: "inventory that's on its way to your location from transfers, purchase orders, or apps."
- On hand: "the sum of your Committed, Unavailable, and Available inventory."
The floor consequence matters. A unit in an unfulfilled order counts as Committed, so it is no longer Available, but it is still in the building: in its bin, in a tote, or at pack-out. On hand also includes Unavailable units, which may be sitting in a quarantine or returns area rather than the pick face. And Shopify knows locations, not bins. So when you check a SKU, count every place it lives in that building, add anything picked but not yet shipped, and compare the total with On hand at that location. Comparing one bin with Available makes every open order look like a missing unit.
What happens on the storefront when the numbers drift?
It depends on which direction the number is wrong.
When Shopify's number is too high, the store sells units you do not have. Shopify's default protects you only against its own number: "When a product reaches zero inventory, customers can't add it to their cart." If the record says 5 and the shelf holds 0, nothing stops the sale, because Shopify has no other way to know. If "Continue selling when out of stock" is turned on, Shopify will also sell past zero. Its definition of out of stock is "when inventory is tracked and the inventory level is at zero or below."
When Shopify's number is too low, the product shows as sold out while it sits on a shelf. This is the quieter failure. There is no cancelled order or angry email, just sales that did not happen. A common version is stock that has physically arrived but has not been received in the system: Shopify says Incoming inventory "isn't available to sell until it's been received at the location."
Which floor events most often fail to reach Shopify?
Every one of these is a physical movement with a matching record. When the movement happens and the record does not, the numbers part.
- Receipts not posted. Cartons are on the dock or already put away, but the purchase order or transfer is still open. The units stay Incoming and unsellable.
- Receipts posted as ordered, not as counted. A purchase order received in full when the delivery was short puts units on the record that never reached a shelf.
- Returns restocked by default. When you refund an order in Shopify, "Restock items" "is selected by default". If the returned unit is damaged, still in transit, or sitting unchecked in a returns cage, a default refund can put it back in the sellable count anyway. Deselect it and restock by hand once the unit has been inspected.
- Mis-picks. A picker ships the neighbouring variant. The order records one SKU going out while the shelf loses another, so one count runs high and the other low by the same amount.
- Damage and loss not recorded. Shopify has adjustment reasons for "Damaged" and "Theft or loss". A crushed unit thrown in the trash without one of those entries stays On hand indefinitely.
- Transfers half-recorded. Shopify's transfer flow commits stock at the origin when the transfer is marked ready to ship, shows it as Incoming at the destination, and makes it available there only when it is received. A box carried between buildings without that flow leaves one location over and the other under.
- Stock walked to a store without a transfer. Shopify POS updates "the inventory count ... for that location" where the sale happens. If cartons were carried from the warehouse to the store without a recorded transfer, the store sells units its record never had and the warehouse record still holds them.
Each of these is an ordinary daily movement. Each one needs someone to record it at the time, in the place it happened.
What happens when two systems write the same number?
A recount will not stick if another system keeps overwriting it.
Apps and warehouse systems update Shopify in one of two ways, and Shopify's developer documentation describes both:
- Set: "Set quantities of specified name using absolute values." The app says "this location has 9".
- Adjust: "Each adjustment modifies the quantity by a delta value rather than setting an absolute amount." The app says "take 1 off".
Shopify also documents why this is hard. On webhooks, the notifications apps use to hear about changes: "Shopify doesn't guarantee ordering within a topic," and "Webhook delivery isn't always guaranteed." On setting quantities: "Opting out of the compareQuantity check can lead to inaccurate inventory quantities if multiple requests are made concurrently." Its advice to app builders is to use "reconciliation jobs to periodically fetch data from Shopify."
The point most sync guides skip follows from those definitions, and it is our reasoning rather than Shopify's: the two kinds of write go wrong in different ways, so they leave different fingerprints.
- A stale set overwrites whatever happened in between. If an app misses or delays the notification of a sale, then sends "9" based on its own older view, Shopify says 9 again even though two units have sold since. The number snaps back to an earlier value shortly after sales.
- A duplicated or dropped adjustment leaves an offset. A "take 1 off" applied twice, or a movement the app never turned into an adjustment, leaves the number wrong by that amount. Where nothing ever sets the number from a count, the offset stays until someone counts, so small gaps pile up over weeks.
Shopify's developer guide recommends the compare check to avoid inaccurate quantities, and says an app can skip it only "because you're the source of truth". That exception assumes there is only one. Two systems that each think they own the same location's number will overwrite each other.
If part of your stock sits at an outside fulfillment service, its location is a special case: a service that manages inventory supplies that location's on-hand levels to Shopify. Correct the number at the service rather than by hand in Shopify.
How do you find out which cause you have?
Work one SKU with a known gap before touching the rest.
- Count the bin and compare with On hand at that location, using the states above. If the gap disappears, there was no gap, only open orders.
- Open the inventory adjustment history for that variant at that location. Shopify shows "the date of the adjustment", "the event that caused the adjustment", and "the staff member, app, or sales channel that made the adjustment". It keeps "only the last 180 days".
- Read the pattern. The same app writing the number back to an earlier value shortly after sales points to an overwrite. Small differences with no matching event, growing over time, point to unrecorded floor movements or adjustments applied twice or not at all. If one app writes everything with a generic reason, the history will tell you less, and the app's own log is the next place to look.
- Check the floor list. Look for open or short receipts, recent refunds with restock on, mis-picks against a neighbouring variant, damage thrown out but not recorded, and transfers not received.
- Correct with a reason. Use the "Count" or "Correction" reason so the next person reading the history knows why the number changed.
- Name one owner per location. Orders, register sales and restocks will always change the number. Decide which single system sets the on-hand count for each location from its own counts, have it use the compare check, and make sure no other app sets that location's number.
If more than a handful of SKUs show gaps, the fix is a cycle-count program rather than a hunt, and our guide to cycle counting covers how to build one without shutting the floor.
How do you keep it from drifting again?
Shopify tells app builders to assume some updates will be missed and to reconcile on a schedule. On the floor that means three things.
- Record movements where they happen. A receipt, a damage write-off or a transfer recorded on the floor at the moment it happens leaves far fewer gaps to find later.
- One owner per number. One system sets each location's on-hand count; everything else changes it only through orders, sales and recorded movements.
- Count by risk. Fast movers see the most events, and high-value items cost the most when they drift. Count both often, and compare against On hand.
If the drift is between several sales channels rather than between Shopify and the shelf, the mechanics of connecting them are covered in how to sync inventory across sales channels, and buffers against the gap in how to prevent overselling across multiple channels.
Frequently asked questions
Why does Shopify show a different number from what is on my shelf?
Usually because something moved on the floor without being recorded in Shopify, or because another system wrote a different number over it. Count every place that SKU sits in the building, add units picked but not yet shipped, and compare the total with On hand at that location, not with Available, because Available leaves out committed units. Then read the inventory adjustment history to see which staff member, app or sales channel last changed the number.
Can Shopify sell more units than I actually have?
Yes, in two ways. If "Continue selling when out of stock" is on for a tracked product, customers can keep buying after it reaches zero, so the count goes negative; this is set per product. And if the recorded number is higher than the real shelf count, Shopify sells against the recorded number, because it has no other way to know. A count correction fixes that one.
How far back can I trace an inventory change in Shopify?
Shopify's inventory adjustment history shows the last 180 days for a product or variant. Each entry records the date, the event that caused the change, and the staff member, app or sales channel that made it. If a drift started more than 180 days ago, the history will not reach its start, so a full count of that SKU is the reliable way to reset the baseline.
Plan the route. We deliver the rest.
See how Binlogic powers last-mile logistics — routing, tracking, and the platform that turns the plan into the package on the doorstep.
Book a callback