Skip to content

UM Multistore Sync

Keeps inventory in step across your Shopify stores and explains every number the app sets.

Plans from Free to $797 help articleslast changed Oct 9, 2026

Coming soon to the Shopify App StoreThe app's privacy policy

← Back to help

Real-time sync, syncs and the activity log

How inventory moves between your stores, what your rule decides, and how to find out in the activity log why a number is what it is.

Real-time sync

When inventory changes in one store for a matched SKU at a linked location, the app sends that change to the other stores in the same location link.

  • It sends the change, not the value. If inventory in store A goes from 10 to 9, store B goes down by one, wherever B currently stands.
  • It never goes below 0.
  • Changes to the same SKU are sent one after another and never overtake each other.
  • The app doesn't send its own writes back.
  • How long transfers took is shown on the Overview page under "Delay in the last hour".

Real-time sync needs no rule. It does have a direction, which you set under "Settings" → "Real-time sync direction":

  • Two-way: every change from every store is passed on. This is the default and the usual setup to prevent overselling.
  • One-way: only changes from the leading store are passed on. Sales in the other stores then don't lower it.

You can switch it off at any time under "Settings" with "Turn off real-time sync". From then on, nothing is sent.

Syncs

A sync is the safety net under real-time sync. It reads the inventory of all matched SKUs in all location links and brings back in line whatever has drifted apart. Your rule under "Settings" → "Sync" decides which number wins:

  • Highest inventory wins. The default.
  • Lowest inventory wins. Careful: if a store reports 0 because it's empty right now, this rule would pull all the others down with it. The safety brake holds back such changes.
  • A specific store wins. You choose the store.

The rule applies to manual syncs, scheduled syncs and the sync that runs when you turn on real-time sync.

A sync leaves out any SKU that real-time sync is paused for, and lists it in the result.

While real-time sync is on, a sync also leaves out any SKU that real-time sync is still working on:

  • The quantity changes while the sync is reading. Real-time sync has already passed that change on, so what the sync read for this SKU is out of date.
  • A transfer for the SKU is still pending because a store was briefly unreachable. The app catches up on it by itself.
  • The quantity has only just changed, and Shopify hasn't told the app yet. That update usually arrives within a few seconds, and real-time sync then passes the change on. If the sync evened things out before that, it would write a sale back, for example. So it waits two minutes from the change.

The next sync includes these SKUs again. If Shopify's update still hasn't arrived after two minutes, it counts as lost, and the sync evens things out by your rule.

This also means: if you correct a quantity by hand and click "Sync now" right away, that SKU can show up as left out in the result. Real-time sync passes your correction on all the same.

When a sync runs

  1. Manually: on the "Sync" page with "Sync now".
  2. On a schedule: under "Settings", set "Scheduled sync" to "Once a day" or "Twice a day", choose the time and click "Save rule and schedule". The time zone is shown below.
  3. When you turn on real-time sync, always first.
  4. On its own, if the app was unreachable for more than 15 minutes while real-time sync was on. Updates from Shopify can get lost in a gap like that.

When a scheduled sync fails

If a scheduled sync fails because Shopify couldn't be reached or slowed down requests, the app tries again on its own. That includes the case where the app wanted to renew its access token for a store and Shopify didn't answer at that moment. The intervals:

  • 5 minutes after the first failure,
  • 30 minutes after the second,
  • 2 hours after the third.

After four attempts, it stops for this scheduled sync. The fourth starts a good two and a half hours after the first. So a sync scheduled for midnight doesn't end up running the next morning. The next scheduled sync runs at its usual time.

On the "Sync" page you see:

  • "Last sync failed" names the cause. While an attempt is pending, it also says when it will run and which attempt it is.
  • Once all attempts are used up, it says so. You can then sync manually or wait for the next scheduled sync.
  • Under "Previous syncs", every attempt stays as its own line. A further attempt carries its number, for example "scheduled, attempt 2".

Not retried:

  • a sync you started manually. The page shows the error, start it again.
  • an error that doesn't go away by itself, for example when the app no longer has access to a store or locations aren't connected. The message then names the next step.
  • a sync the safety brake stopped. That isn't an error, it's the brake's result.
  • the sync the app starts after an interruption of its own (item 4 above).

A further attempt never starts alongside a running sync, it waits for that one to end. It is dropped if another sync has completed in the meantime, if the next scheduled sync is due, or if you change the schedule.

Reading a sync result

"Last sync" shows when it ran, whether it was manual or scheduled, and what came out of it:

  • written: how many inventory levels it set.
  • rejected: the inventory changed between reading and writing. That's intended, the next sync picks them up. The app sends the changes for a store to Shopify in batches, up to 100 per request, and Shopify rejects the whole request if one of the inventory levels in it has changed. So the app sends the others again in the same run, without the one that changed. If another one changes at that very moment, they wait for the next sync too and count as rejected.
  • left out: real-time sync is still working on these SKUs (see above). That's intended too. The SKUs are listed below, each one links to the activity log.
  • failed: worth a look in the activity log.
  • "All syncable inventory already matched." means there was nothing to do.

Further notices below the result are explained in the article "Notices and what to do".

Earlier syncs

"Previous syncs" lists the last eight runs with the time, whether the run was manual or scheduled, and the result: "written" with the number, "running", "stuck", "stopped" or "failed".

  • failed: the line right below says why the run failed. If the app doesn't know the cause, the technical message for support is shown there too.
  • stopped: the safety brake stopped the run and nothing was written. The line below says what triggered it.

For the latest sync the reason isn't in the list. It's at the top of the page, together with the next step. Earlier runs leave the next step out on purpose: what to do depends on how things stand today.

The safety brake

Inventory at 0 can mean sold out, but it can also mean a stuck import or an empty store. So that a mistake like that doesn't empty every store, there are two brakes.

  • In syncs: a SKU that would drop to 0 even though another store has stock isn't written. It's reported as "held back". If that affects at least 5 SKUs and more than 10% of the syncable SKUs, the whole sync stops and writes nothing.
  • In real-time sync: if more than 20 inventory levels in one store drop to 0 within 10 minutes, the app pauses real-time sync for that store only. The other stores keep running. Once you've checked, you resume it from the Overview page.

The brake against a second sync app

Two apps that sync the same stores keep pushing each other on (see "Getting started", section "No second sync app"). The app can't prevent that. It limits it. Don't rely on this alone: in a test on October 6, 2026 the brake paused after the first round. By then, inventory was already at 140 instead of 35 in both stores. The safe protection is still to turn the other app off.

How it works:

  • If a store reports the same change again that the app has just transferred there, the app asks Shopify whether there's an order behind it. If so, it transfers as usual.
  • If there's no order behind it, the app still transfers it at first. It pauses real-time sync for that one SKU as soon as this has happened in two stores of the same location link within 15 minutes, or three times in the same store. By then, the change has already been counted one to three times too often in each store, because the second app writes first.
  • If this happens to three SKUs within 30 minutes, it pauses real-time sync for the whole group.

What it doesn't see:

  • If the second app writes a different amount than the one that was just transferred, that doesn't count as suspicious. This happens when it catches up on several changes at once. In that case it gets noticed one round later at the earliest.

Adding the same amount up to three times in a row in one store doesn't trigger anything. That happens when several returns of the same variant are restocked. The fourth time within 15 minutes, the app pauses the SKU: with no order behind it, that looks like a second app. What to do when a SKU is paused is covered in the article "Notices and what to do".

Reading the activity log: "Why is this at 3?"

Each row in the activity log is a number the app set in a store, or tried to set. To find the explanation for an inventory level:

  1. Click a SKU, for example next to "Last transfer" on the Overview page or under "Matched" on the Matching page. Or open "Activity log" and enter the SKU in the filter, spelled exactly as in the store.
  2. You see the history of that SKU, newest first.
  3. The top row for the store explains why the inventory is what it is right now.

Each row has three parts:

  • What triggered it, such as "Inventory in store-a.myshopify.com went down from 4 to 3." or "Manual sync using your rule."
  • What the app did, such as "Transferred to store-b.myshopify.com: 4 → 3."
  • What to do, if there's anything to do.

The app deliberately doesn't say "sale". Shopify only reports that inventory moved, not why. Calling a return a "sale" would be a guess.

Results in the activity log

  • Written: the number is in the store.
  • Rejected: the inventory in the target changed in the meantime. Nothing to do: real-time sync reads again and repeats the change, and for a sync the next one catches up. If the row says "Shopify rejected the whole request", it wasn't this inventory level that changed but another one in the same request. The next sync catches up on that too.
  • Held back: the safety brake wrote nothing. Check whether one of the stores is empty or incomplete right now.
  • Paused: real-time sync was paused for this SKU, so the change didn't move to the other store. The Overview page tells you what to do.
  • Skipped: the linked location doesn't track inventory for this item. The app never turns that on by itself.
  • Failed: the row names the cause and the next step.

Filtering

Under "Filter" you narrow things down by SKU, store, result and date range ("From", "To"), then click "Apply filter". "Clear filter" shows everything again. "Older entries" takes you further back. The activity log only ever shows the stores in your own group.