JUN 1, 2026Guides

Why inventory oversells across Shopify, Amazon, and your 3PL: sync, source of truth, and the buffer that stops it

You oversold. A drop went out, orders came in faster than your systems could talk to each other, and now you're emailing customers to say the thing they bought isn't actually in stock. The reflex is to blame the sync — but the sync mostly did its job. A sync is a scheduled push, not a promise, and underneath it three systems were quietly disagreeing about how many units you had the whole time. A seller in r/FulfillmentByAmazon described the daily version of it: "Just spent three hours trying to reconcile missing units because the amazon api decided to randomly stop talking to my woocommerce site over the weekend. again." Here is how to find where the counts drift, and how to set things up so the drift can't turn into an oversell.

The most useful answer to this whole problem is sitting in one buried comment on that thread: "you need a single source of truth for inventory, not three systems arguing about who's right." That is correct, and almost nobody connects it to an actual procedure. Everyone else either names one cause (returns, ghost entries) or plugs a tool. So that is what this is: the buried insight, turned into steps you can run tonight.

Why "everything syncs" and the numbers still disagree

A sync is a scheduled poll, not a live mirror. Most channel-to-channel inventory connectors — and the Zapier-in-the-middle setups people bootstrap — check for changes on an interval and push the new number. Between polls, the systems are out of date by design. The sharpest comment on that FBA thread named the failure exactly: the "zapier-in-the-middle setup breaks specifically during high volume because zapier polls on a schedule (usually 5-15 min depending on your plan)." During a normal week you never notice. During a drop, orders land inside the poll window, two channels both sell the last unit, and you are oversold. A seller in a BFCM thread watched it hit a peer: "Had a buddy who oversold by like 300 units last year cause his shopify and amazon werent talking properly."

The second reason is quieter: the systems do not even count the same thing. Shopify splits stock into on hand, committed, available, and unavailable — on hand is the sum of the other three, available is what is actually sellable, committed is placed-but-not-yet-fulfilled. Your ERP or accounting system, meanwhile, tracks a quantity for valuation, not for selling. So "available" in Shopify and "quantity on hand" in QuickBooks are answering different questions, and expecting them to be equal is the mistake. A merchant in r/smallbusiness hit exactly this wall — "Even when orders are syncing correctly, inventory quantities still do not match between Shopify and QuickBooks." A commenter got the diagnosis right: "most mismatches I've seen come from inventory logic not being mirrored, not just sync delays."

The three reconciliations hiding inside "my inventory doesn't match"

"Inventory doesn't match" is three different problems wearing one complaint. You cannot fix it until you know which one you are staring at, because each has a different cause and a different place to look. Sort the gap into one of these first:

ReconciliationWhat you compareWhat a gap meansWhere to look
Physical ↔ systemA real count of what is on the shelf vs the system on-handShrinkage, damage, theft, receiving errors, miscountsThe warehouse / 3PL floor and your receiving log
Source of truth ↔ channelYour master available vs what each storefront showsSync drift or latency — the push has not landed yetThe connector / sync logs and their timestamps
Ops qty ↔ finance qtySellable units (OMS/Shopify) vs valuation qty (ERP/QuickBooks)Different counting logic — returns, bundles, transfers, ghost entriesThe accounting inventory ledger, not the sync

Most people try to reconcile harder against all three at once and get nowhere. And this is not a rounding-error problem you can will away: a peer-reviewed study of nearly 370,000 retail inventory records found 65% of them were inaccurate. A gap between the system and the shelf is the normal state of inventory, not the exception. So the goal is not a perfect match. It is knowing which of the three is drifting, and by how much.

Pick one source of truth — and make the others bow to it

The fix the experienced sellers keep landing on is one line: "you need a single source of truth for inventory, not three systems arguing about who's right." Pick the system that physically knows what shipped — usually your OMS, your 3PL/WMS, or your ERP, not the storefront — and declare it the authority on available-to-sell. Every channel receives its count from that system; none of them argue back. This is the same move as reconciling your OMS against the source of truth, applied to units instead of orders. The storefront is a display. The warehouse is the truth. When they disagree, the warehouse wins and the channel gets corrected — never the other way.

Set a buffer that covers the sync gap

While any lag exists between your source of truth and a channel, a buffer is the only thing standing between a fast sales window and an oversell. This is plain safety stock, sized to the one risk you can actually measure: how many units can sell on a channel before the next sync corrects it. The math is boring and it works:

Buffer per SKU, per channel
---------------------------
sync_latency   = minutes between inventory pushes (worst case, peak load)
peak_velocity  = max units/min that SKU sells on this channel during a drop

buffer = ceil(sync_latency * peak_velocity) + safety_margin

Example — a hot SKU during a launch:
   sync_latency  = 10 min      (connector polls every 10 min under load)
   peak_velocity = 1.2 units/min
   buffer        = ceil(10 * 1.2) = 12 units   (+ a few for safety)

Stop selling on the channel at 12 units on hand, not 0.
Those last 12 units are the cushion the sync delay can burn
through before the correction lands.

Set the buffer high on your fastest movers and during known spikes; drop it back when velocity is predictable, because every buffered unit is a unit you are choosing not to sell. The buffer is a patch over latency, not a replacement for the source of truth — it buys you the minutes the sync needs, and nothing more. Shrink the latency and you shrink the buffer.

Reconcile on hand against the floor: the shrinkage check

This is reconciliation #1 — the one your sync can never fix, because the gap is physical. Run it on a cadence (small, frequent cycle counts beat one giant annual count), against whatever actually holds your stock. For FBA, Amazon hands you the raw material directly: the Inventory Ledger report shows your starting balance, units received, customer orders and returns, adjustments, and reconciliation events for damaged or lost units. The seller who posted that "the number of orders I received doesn't match with inventory" was seeing exactly this — units that left the system without leaving as a sale.

  1. Count a slice of SKUs physically (a cycle count) — start with your highest-velocity or highest-value items.
  2. Pull the system on-hand for those same SKUs as of the count moment. Freeze movement during the count, or the numbers will never tie.
  3. Diff count vs system. For FBA, pull the Inventory Ledger and inventory adjustments for the same window so the events are itemized for you.
  4. Classify each gap: received-not-logged, shipped-not-decremented, damaged, lost, or miscount. The classification is the answer; the number is just the flag.
  5. Adjust the system to match the physical count, and file reimbursement claims for anything the warehouse lost. The count wins, every time.

Reconcile each channel against the source of truth: the drift check

This is reconciliation #2 — pure data, no warehouse required, and the one you can automate. You are comparing your master available against what each channel is currently showing, SKU by SKU, to catch drift before it becomes an oversell. It is the same two-file discipline as reconciling two systems by hand, pointed at inventory:

  1. Export available-to-sell by SKU from your source of truth.
  2. Export the inventory each channel currently shows (Shopify "Available," Amazon "Available," and so on).
  3. Join on the SKU — the primary ID the whole reconciliation hangs on. If your SKUs are not identical across channels, fix that first; nothing else works until they are.
  4. Clean the exports before you match. A SKU that Excel mangled into a number, or a stray encoding mark, will fake a mismatch — these are the CSV gotchas that quietly break a reconciliation.
  5. Diff the two columns. In a spreadsheet, COUNTIF and MATCH find the rows present in one file and missing from the other; a simple subtraction column finds the SKUs that exist in both but disagree.
  6. For every SKU that is off, check the sync timestamp. A gap with a recent successful sync is real drift to investigate; a gap with a stale or failed sync is just a push that did not land — re-run it.

A worked example: where the 12 units went

One SKU, three systems, the end of a launch day. The storefront says one thing, the warehouse another, the books a third. Walk it the way you would walk it live:

SystemShows availableWhy
3PL / source of truth88The real count: 100 received − 12 shipped
Shopify (channel)94Sync is two polls behind; 6 of the 12 shipments have not decremented yet
QuickBooks (finance)1002 customer returns re-added to quantity, and a bundle SKU never relieved its components

Three different numbers, three different stories, and not one of them "broken." Shopify is drift — reconciliation #2: re-sync now, raise the buffer next launch. QuickBooks is counting logic — reconciliation #3, an accounting fix for the returns and the bundle relief, the same family of gap covered in where NetSuite inventory and the GL disagree, not a sync problem at all. The 3PL is right, which is the entire point of making it the source of truth. And notice the oversell risk lived only in Shopify's six un-decremented units — a buffer of 12 would have absorbed it without a single apology email.

When do you actually need software for this?

Two files and a spreadsheet reconcile inventory across two or three channels fine — the by-hand method scales further than people expect. You start needing real tooling when the channel count climbs, when the sync interval has to shrink toward real-time, or when a launch's velocity outruns any buffer you would be willing to hold. Multi-channel inventory tools — SkuVault, Veeqo, Cin7 and the like — exist to be that single source of truth and to push faster than a polling middleware can. They earn their keep when manual re-syncs and held buffer cost you more than the subscription. What they do not do is the physical reconciliation: no tool knows a unit was damaged in the warehouse until someone counts it.

Whatever you use to move the numbers, the job underneath is the same — one source of truth, a buffer sized to the lag, and a regular check that the channels and the floor still agree. That is the reconciliation. The tool is just how fast you get to run it.

Frequently asked questions

Why does my inventory oversell even though my systems are synced?

Because a sync is a scheduled push, not a live guarantee. Most connectors poll for changes on an interval — often every 5 to 15 minutes. During a fast sales window, two channels can both sell the last unit inside that interval before the decrement reaches the other one. The sync is not broken; it is just behind. A safety buffer sized to cover the poll interval is what prevents the oversell while the lag exists.

What should be my source of truth for inventory?

The system closest to the physical event — usually your OMS, your 3PL or warehouse system, or your ERP, not your storefront. It is the one that knows what actually shipped and what actually arrived. Every sales channel should receive its available count from that system and never overwrite it. When two systems disagree, the one nearest the warehouse wins.

Why doesn't my Shopify inventory match QuickBooks even when orders sync correctly?

Because they count different things. Shopify tracks sellable units and splits them into on hand, committed, available, and unavailable. QuickBooks tracks a quantity for valuation, which moves on returns, refunds, bundles, location transfers, and the occasional ghost entry. Those are different logics, so the two numbers were never meant to be identical. Reconcile them as an accounting question, not a sync problem.

How do I calculate an inventory buffer to prevent oversells?

Multiply your worst-case sync latency in minutes by the SKU's peak sales velocity in units per minute during a spike, round up, and add a small safety margin. That is the number of units that could sell before the next sync corrects the channel. Stop selling that SKU on the channel when on-hand hits the buffer rather than zero. Raise it for fast movers and known spikes; lower it when demand is predictable.

Do I need inventory software, or can I reconcile by hand?

A spreadsheet handles two or three channels: export available-to-sell from your source of truth and from each channel, join on SKU, and diff. You start needing dedicated multi-channel software when channels multiply, when you need the sync closer to real-time than a polling tool allows, or when launch velocity outruns any buffer you would hold. Software keeps the systems agreeing faster; it still cannot count the warehouse floor for you.