The r/shopify thread is almost a genre at this point. A store has its best day in months, a TikTok lands, a marketplace listing takes off, a flash sale clears the homepage, and then, a day later, the founder is writing the same email to a dozen customers: I'm so sorry, but the item you ordered is actually out of stock. The product page still said "available." The checkout still took the money. The number was just wrong, and nobody knew until it was time to pack the box.
That's overselling: selling a unit you no longer have. And of all the operational pain points merchants complain about publicly, it's the one they describe in the angriest terms, not because it's the most frequent, but because it's the hardest to take back. Running out of stock means a customer couldn't buy. Overselling means they already did, got the confirmation email, told their kid the present was coming, and now you have to walk it back.
Out-of-stock is a missed sale. Overselling is a broken promise. One costs you a customer you never had; the other costs you a customer you already won.
Where the number goes wrong
Overselling is almost never a counting mistake inside Shopify itself. It's a sync problem. The moment a store sells in more than one place, Shopify plus a physical POS, plus Amazon or eBay, plus the occasional wholesale order, plus a "DM me to buy" Instagram channel, there is one pile of physical stock and several systems each keeping their own tally of it. Nothing moves the number in all of them at once.
So the last three of a popular SKU sell on Amazon at 2:14pm, and Shopify doesn't find out until the nightly export runs at midnight. For ten hours, the store cheerfully sells inventory that's already gone. Industry surveys put the scale of this bluntly: roughly 40% of retailers say they cancel at least one in every ten orders because of inaccurate inventory data, and average retail inventory accuracy sits famously low, often cited in the 60-65% range for stores without real-time sync. The merchant isn't careless. The architecture is just lying to them on a delay.
Why the manual fixes quietly fail
Every merchant eventually rigs up a defense. A spreadsheet they reconcile on Sunday nights. A "safety buffer" where they hide the last five units so the count can be wrong by up to five before it hurts. A Shopify Flow rule that hides a product when it hits zero. A cheap sync app bolted between two channels. Each helps. None of them hold under load.
The spreadsheet is stale the moment a sale comes in. The safety buffer is a guess, too small and you still oversell, too large and you're sitting on unsellable stock and killing your own conversion. Flow rules fire on Shopify events only, so they're blind to the Amazon sale that actually caused the problem. And the basic sync app handles the happy path, one sells here, decrement there, but falls over on everything real: a bundle that draws from three SKUs, a pre-order that should oversell on purpose, a return that puts a unit back, a warehouse recount that contradicts every channel at once.
In a node-based builder, covering those cases means drawing a graph nobody has the patience to draw: a branch for bundles, a branch for pre-orders, a branch for partial restocks, a branch for the channel that's down for maintenance and can't be updated right now. So merchants build the simple version, it works in the demo, and it oversells the first time a SKU gets popular on two channels at once.
What the automation actually has to do
The real job isn't "decrement a number." It's: watch every channel continuously, treat the lowest trustworthy count as the truth, push that truth everywhere within seconds, hold a smart buffer on fast-movers, and, when two systems genuinely disagree, know which one to believe and who to wake up. That's a set of judgement calls, not a single rule. Written as a Dugong playbook, in plain prose, it reads like this:
# trigger
When stock changes on any channel, or every 2 minutes
# steps
1. Read the live available count for each SKU on every channel
2. Reconcile to a single source of truth (lowest verified count)
3. Push that number to Shopify, Amazon, eBay, and POS at once
4. Hold a dynamic buffer on fast-movers during a sale
5. If a SKU is about to hit zero → hide it or flip to
"notify me" before it can be oversold
6. If two channels disagree by more than a unit →
pause sales on that SKU and ping me in Slack with both numbers
7. Account for bundles, pre-orders, and returns correctly,
not as plain decrements
Seven lines. The compiler fills in everything underneath: the per-channel API calls, the reconciliation logic, the rate limits, the retry when Amazon's endpoint times out, the bundle math that maps one sale to three component SKUs. The merchant named the outcome, never sell what we don't have, and let the compiler decide what it had to be to deliver it.
The real win: catching the order before it ships
Even perfect sync has a seam, the few seconds between two simultaneous checkouts on different channels. So the second half of the playbook isn't prevention, it's graceful recovery. The same automation that keeps counts honest can watch new orders and catch the rare oversell before it becomes a broken promise.
# trigger
When a new order comes in for a SKU at or below zero
# steps
1. Check real stock across the warehouse and all channels
2. If it can still be fulfilled → let it through, resync counts
3. If truly oversold → hold the order before fulfilment and
offer the customer a backorder ETA, a swap, or an instant refund
4. Email them warmly within minutes, not a day later
5. Log the SKU and channel so I can see what keeps overselling
A customer who hears "heads up, that one just sold out, want us to ship the navy instead or refund you today?" within minutes of ordering is mildly disappointed. A customer who hears it three days later, after they've been waiting, leaves a one-star review. Same shortfall, completely different outcome, and the difference is entirely about whether anything was watching.
Why this is a compiler problem, not an app problem
There are plenty of inventory-sync apps in the Shopify App Store, and the good ones genuinely help. But they sync the way a thermostat works: one number, one rule, applied everywhere. They don't know that this SKU is a bundle, that one is a planned pre-order, that the spike at 9pm is a sale and the buffer should tighten, or that when the warehouse count and the channel count disagree, a human should look before more units go out the door. Those are decisions, and decisions don't fit in a settings panel.
A natural-language compiler is the unlock because the hard part of overselling was never the subtraction, it was the dozen exceptions stacked on top of it. You can describe those exceptions in a paragraph to a new operations hire. You could never draw them in a node graph and keep it maintainable. That gap, between what a merchant can describe and what the old tools could compile, is exactly where the unbuilt automations live.
The workflow worth building this week
If you sell in more than one place and you've ever sent a "so sorry, it's actually out of stock" email, this is the automation to build before any tag rule, any cart-recovery sequence, any analytics dashboard. It protects the two things that are hardest to win back, customer trust and your payment processing, and it does it on exactly the days you most want to be celebrating instead of apologizing.
Describe it the way you'd brief a careful operations manager: never sell what we don't have, keep every channel telling the same truth, and if something slips through, catch it in minutes and make it right before the customer is even annoyed. That's the whole brief. The compiler handles the rest.
If you're a Shopify merchant who's been burned by overselling, or you've built a sync playbook that finally holds during a
sale, the inbox is open: field-notes@dugong.live.
We're collecting case studies for the next issue.