Documentation
Catalog & inventory6 min readUpdated 28 July 2026

Inventory & stock sync

One stock pool, many channels: how availability is calculated, how buffers stop oversells, and what happens when two channels sell the last unit.

On this page

Stock is the number everyone argues about. The model here is deliberately boring: quantities live on variants at locations, and everything a channel sees is derived from them.

The four numbers

on_handintegerrequired

Physically at the location. Changes when goods arrive, ship or are counted.

reservedintegerrequired

Committed to orders that have not shipped yet.

availableintegerrequired

on_hand - reserved. What can still be promised to a customer.

bufferinteger

Held back per channel so a slow marketplace feed cannot sell what you no longer have.

What a channel is told is available across its eligible locations, minus its buffer, floored at zero.

Why buffers exist

Marketplaces do not read your stock in real time; they accept a feed and act on it minutes later. In that window you can sell the same unit twice. A buffer is the price of that latency.

Tip

Start with a buffer of 1–2 units on fast-moving SKUs at high-latency channels, and zero on your own storefront, which reads availability directly. Then tune it against your actual oversell rate rather than a rule of thumb.

Reservations and the last-unit race

When an order is created, the units are reserved immediately, before any channel is notified. Reservation is the atomic step — everything downstream is a consequence of it.

1
Order arrives from channel A

The units are reserved against the resolved location.

2
Availability recalculates

available drops for every channel at once, because they all read the same pool.

3
Every other channel is updated

Your storefront is instant. Feed-based channels are updated on their next push, which is where the buffer earns its keep.

4
Order from channel B for the same unit

If it arrives before the feed lands, it is accepted by the marketplace and flagged here as an oversell, with the shortfall and the suggested resolution attached. It is not silently fulfilled and it is not silently dropped.

Locations and eligibility

Every location has a type — warehouse, retail, third-party — and each channel declares which locations it can sell from. A shop's stock can be excluded from marketplace availability entirely, or included with a heavier buffer.

This is also what makes ship-from-store possible without giving marketplaces the ability to sell the shop empty.

Adjustments have reasons

Every movement is recorded with a reason: receipt, sale, return, transfer, damage, count. Nothing changes on its own.

ReasonEffect on on_handTypical source
ReceiptIncreasePurchase order arriving
SaleDecrease at fulfilmentOrder shipped
ReturnIncrease after inspectionReturns flow
TransferMove between locationsInternal replenishment
DamageDecreaseManual, with a note
CountSet absoluteStocktake

A stocktake sets the absolute number and records the delta, so the difference between what you thought and what you had is itself a reported figure.

Worth knowing

Bulk-setting on_hand from a spreadsheet at 3am is the most common way to create a phantom oversell. Import counts as a count adjustment with a timestamp, not as a silent overwrite.

Low stock and replenishment

Thresholds are set per variant per location, and breaching one raises an event you can act on — a notification, a purchase order draft, or a webhook into whatever your buying team already uses.

Next: Channels overview, where this availability turns into listings.

Ask about this page withChatGPTClaudePerplexity