A storefront is a noticeboard, not a scoreboard.
It does not watch the warehouse. It shows the last thing somebody pinned to it. Mossery holds the original count, and everything a shopper sees is a copy that was sent outward at some point in the past.
Once you see it that way, the whole Sync stage stops being mysterious. Copies can be late, copies can be missing, and copies can be sent to the wrong noticeboard — but the original is the original, and this app owns it.
This page covers:
- What sets an update going
- Three things must line up
- Which locations a storefront may advertise
- What number actually goes out
- The nightly check heals in one direction only
- When a push fails
What sets an update going
Every stock movement queues an update. Nothing is sent the instant it happens.
When anything changes what you own — a delivery, a count, a transfer, an assembly, a fulfilment — a permanent entry is written to the stock ledger, and that entry drops a job onto an outgoing queue. The job says only this product, at this location, needs re-sending. It carries no quantity.
That last detail is what makes the whole thing safe. When the job is picked up, the current level is read fresh and sent as an absolute value — "this product now has 42 here" — rather than "add three". Sending the same job twice therefore changes nothing, and two jobs for the same product and location collapse into one rather than queueing behind each other.
The queue is drained twice over:
- Immediately, by whatever just changed the stock, so a big flow like a receiving or an approved count goes out inside the same action.
- On a sweep, roughly every minute, catching anything the first pass missed because it crashed, timed out, or errored.
Each pass takes a bounded batch and leaves the rest for the next one, so a thousand-line change becomes a few minutes of steady sending rather than a burst your storefront would rate-limit anyway.
A queue that is long but moving is healthy. A queue whose oldest item has not budged in days is stuck, and that is worth escalating rather than retrying.
Three things must line up
An update is only attempted when all three are true. Any one missing and the push is a silent no-op — not an error, because nothing was ever attempted.
1. The product is matched to that store. A product page can show a "syncing" badge and still have nothing behind it. The badge means a link exists; the thing that actually carries stock outward is a separate record holding the store's own identifiers for that item. When one is present and the other is missing, every update quietly does nothing.
2. The location is matched to a location on that store. Your warehouse has to correspond to a specific place in the storefront's own list of places. Without that pairing there is no address to send the number to. Crucially, the app will not guess: no match means no target, and the update is skipped.
That refusal is the scar of a real failure. When guessing was allowed, a system handed one store's location identifier to a different store, and the rejected pushes piled up unnoticed for weeks — hundreds of thousands of error records, a full disk, and eventually an outage. Skipping is boring and correct.
3. The connection is switched on. Each connected store sits in one of three states:
| State | What happens |
|---|---|
| Live | Updates are sent |
| Shadow | Everything is calculated and recorded, nothing is sent |
| Paused | Nothing happens at all |
Shadow is the deliberate halfway house used while you validate a new integration: the app shows what it would have sent without touching the live store, so you can compare against whatever is currently in charge. A single product can be promoted out of shadow to prove the path end to end before the whole catalogue follows.
Which locations a storefront may advertise
Stock is real where it sits, and not all of it is yours to offer.
Only locations you actually sell from are pushed. A warehouse, yes. But stock held by a consignment partner, sitting on a stall at a weekend event, parked with a production partner, or half-consumed inside an assembly in progress is never advertised — no matter how the mappings are configured.
The reason is simple. Those units are already promised to someone, or are not in a saleable state. Offering them online would sell the same physical item twice: once to a shopper, once to the partner already holding it.
This is also the usual answer to "we clearly have stock, why does the store say none". If the units live somewhere that store cannot sell from, the store is correct to ignore them. The fix is either to map that location to the store, if it genuinely fulfils online orders, or to transfer the stock somewhere already mapped.
What number actually goes out
For most products it is simply the finished units at that location.
Built products send their capacity too
A product assembled from components would read as sold out the moment its finished units ran out, even with a shelf full of parts. So a built product advertises its derived availability: finished units on hand, plus how many more its components could produce right now.
Two rules keep that honest:
- The capacity is worked out from the components at that same location. Parts sitting in two different buildings cannot become one finished unit, and treating them as if they could once made a kit advertise thirteen when the site that would build it could manage three.
- The capacity is added only at the location where assembly happens. Everywhere else sends finished units only. Otherwise the same build capacity would be counted once per location and the storefront's total would multiply it.
A product whose components are all made to order has no stock-bound limit at all, and is sent out with a generous standing figure instead of a calculated one.
Selling at zero is a separate instruction
Alongside the quantity, each product carries an instruction about what the store should do when that quantity hits zero.
A ready-stock product should stop selling — zero means sold out. A made-to-order or hybrid product should keep selling — zero is its normal resting state, and refusing orders would be refusing the business the product exists for. That instruction mirrors the product's stock mode, and it is set when the listing is created, so an older listing built before the rule existed can sit there denying orders. A periodic pass finds those and corrects them.
The nightly check heals in one direction only
Once a night, the app compares itself against each live store, item by item.
Anything that disagrees is recorded as drift, with both figures side by side, so you can see whether the gap is one product or a systemic problem. Then it corrects — but upward only.
- The store reads lower than you. The app re-sends its own number. This is the "we have stock and it still says sold out" case: a stale push, a failed send, or somebody editing the store by hand. Re-asserting is safe.
- The store reads higher than you. Nothing is corrected automatically. The drift is recorded and left alone.
That asymmetry is deliberate and worth understanding, because it is the single most common surprise in the Sync stage. Correcting downward at night would clobber a legitimate in-flight change — the store may be right and the app may be a few seconds behind. So the app only ever pushes a number up on its own initiative, and every overcount is left for a human.
The practical consequence: an overcount does not self-heal. If a store is advertising more than you hold, it will keep doing so until the underlying cause is fixed and a real stock movement re-triggers a push. Waiting another night will not help.
The nightly pass is also capped by both count and time, so a large backlog cannot become a write storm against your store. Whatever it does not reach tonight is re-detected and picked up tomorrow.
When a push fails
Failures are recorded, not swallowed, and always against one specific store.
Each failure writes an entry naming the product, the store, the location and the reason. That per-store detail matters: a fault on one channel used to be filed against another, which is how a month-long failure on one storefront was misread as a problem with a completely different one.
One refusal is worth knowing about because it looks like a failure and is actually a safety catch. When a product was first linked, the app remembered which item on the store it pointed at. If that item is later renamed or reused for a different product, the link now points at somebody else's listing. Rather than write your stock onto it, the app refuses the push and records why. Re-linking the product repairs it.
Everything else follows the ordinary shape: fix the cause the error names, then let a real stock movement re-queue the item, or retry it directly.
Explore
A product shows 0 online, but you have stock. The three checks to run, in order, when a specific product disagrees with a specific store. Learn more →
When stock actually moves. What creates the ledger entries that set all of this in motion. Learn more →
The three numbers of a built product. Where the derived availability a built product advertises comes from. Learn more →