Where catalogue drift comes from
Two stores that started identical rarely stay identical, and it is almost never one dramatic failure. Drift is an accumulation of small, individually reasonable events. Here are the ones that actually produce it, in the order we see them.
1. The event that never arrived
Most syncing is event-driven: the store fires a webhook, the app catches it and copies the change. Shopify states plainly that delivery is not guaranteed. A missed delivery produces no error anywhere: the first store saved the change, the app was never told, the second store keeps the old value. Nothing to retry, nothing to alert on.
This one compounds. Every missed event is permanent until something compares the two catalogues again from scratch.
2. Edits made in the wrong store
Someone opens the second store's admin and fixes a typo there, because that is the tab that was open. In a one-way setup the edit survives until the next time that product changes upstream, and then it silently disappears. In a two-way setup it propagates and overwrites the version someone else was working on.
Neither behaviour is a bug, but merchants read both as one: "my change vanished". This is the single most common source of drift in stores with more than one person editing.
3. Stock counted per location
Inventory is not a number on a product; it is a number per variant per location. Two stores rarely have the same locations, so a sync has to decide how to add them up. Add a warehouse on one side, and the total changes on that side only - no event about the product itself is ever fired, because the product did not change.
Editing stock does not update a product's timestamp either, which is why a sync that watches products alone can miss inventory entirely. More on multi-location inventory.
4. Renames that break the match
Copies are matched by something: SKU, handle, barcode, or an internal link. Rename that key on one side and the two products stop being the same product as far as the app is concerned. The usual outcome is a duplicate - the app cannot find the copy, so it creates one - and now the catalogue contains both, with stock split between them.
Variants are the sharper version of this. A variant identified by its option values ("Blue / L") changes identity when someone renames the option, and everything attached to it - inventory, barcodes, metafields - has to find a new home.
5. Bulk operations that outrun the sync
A price update on three thousand products, an import from a supplier feed, a theme migration that rewrites metafields. These arrive as a flood of events, and every sync app has rate limits. What gets dropped, deferred or partially applied during a flood is rarely visible afterwards: the job finished, the store looks busy and normal, and a few hundred products quietly did not travel.
6. Apps writing to the same fields
A pricing app, a translation app, a bundling app and a sync app can all legitimately write to the same product. When two of them disagree, the field flips back and forth - each one "fixing" what the other just did. Stock that changes on its own without an order is the classic symptom.
What actually stops it
None of these are solved by syncing harder, because the failure is not in the copying - it is in the assumption that copying happened. The only thing that catches all six is periodically comparing the two catalogues field by field and reporting what differs, rather than trusting the event stream that produced them.
You can do that by hand for a handful of products - here is the manual procedure - and it is worth doing once, if only to see what turns up. Past a few hundred products it stops being realistic, which is what a sync audit automates: StoreTwin re-checks changed products hourly and compares both full catalogues daily, naming every difference by product and field with the value from each store. That part runs on the free plan over a catalogue of any size, including one another app is syncing.