Shopify Inventory Sync: How Real-Time Sync Actually Works
TL;DR
Shopify inventory sync relies on webhooks that fire within 1-3 seconds but fail silently in roughly 1-2% of cases. Reliable sync requires a webhook receiver, idempotency checks, an event queue, and a scheduled reconciliation pass to catch drift before it reaches customers.
Shopify inventory sync sounds straightforward. An order ships, quantities drop, everything stays in step. In practice, syncing inventory between Shopify and any external system is one of the trickier operational problems ecommerce teams face at scale. According to a 2024 IHL Group report, inventory distortion (including sync errors) costs retailers $1.77 trillion globally each year.
This guide explains how the sync mechanism actually works, where it breaks, and what you need to build to keep quantities reliable.
How Shopify pushes inventory changes
Shopify uses webhooks to notify external systems whenever an inventory-relevant event occurs. The key webhook topics for inventory are:
inventory_levels/update— fires when an on-hand quantity changes at a specific locationinventory_items/update— fires when an inventory item’s tracking settings changeorders/create,orders/fulfilled,orders/cancelled— indirectly affect committed and available quantities
When an order ships and Shopify marks it fulfilled, it fires a fulfillment webhook, updates the inventory_level for each variant at the fulfillment location, and fires an inventory_levels/update event. That whole chain completes within 1-3 seconds under normal load.
The external system (a WMS, a third-party app, or your own integration) receives the webhook payload and updates its own records. That is the happy path.
Why sync reliability is not guaranteed
Roughly 1% to 2% of Shopify webhook events are missed or delayed
Shopify’s own documentation states that webhooks are delivered on a best-effort basis. In practice, roughly 1-2% of webhook events are delayed, duplicated, or missed entirely. That number sounds small until you are processing 500 orders per day and 5-10 quantity updates per day are silently wrong.
Three failure modes cause the most problems:
- Missed delivery: The receiving server was down or responded too slowly. Shopify retries for up to 48 hours, but if the endpoint never recovers in that window, the event is lost.
- Out-of-order delivery: Two rapid updates to the same SKU arrive in reversed sequence, leaving you with a stale quantity. This is common during flash sales when a single SKU gets 20+ adjustments per minute.
- Duplicate delivery: The same event fires twice (a documented webhook behavior), and your system processes both, double-adjusting the quantity.
All three show up as real count discrepancies if you are not handling them with explicit safeguards. Teams that track these errors typically find that 60-70% of sync-related discrepancies trace back to missed or out-of-order deliveries rather than duplicate events.
Webhook delivery timeline
Understanding timing helps you design your retry and reconciliation windows:
| Event | Typical latency | Notes |
|---|---|---|
| Order placed to webhook fired | 1-3 seconds | Under normal Shopify load |
| Webhook retry (first attempt) | ~5 minutes | After initial failure |
| Webhook retry window | Up to 48 hours | Shopify stops retrying after this |
| Webhook payload expiry | 48 hours | No recovery after expiry |
| Shopify rate limit (REST) | 2 req/sec standard | 40 req/sec on Shopify Plus |
| Shopify rate limit (GraphQL) | 1,000 cost points/sec | Throttled, not hard-capped |
Polling as a fallback
How often should you poll the Shopify Inventory API?
Some integrations supplement webhooks with periodic polling of the Inventory Level API. Polling queries GET /admin/api/2024-10/inventory_levels.json on a schedule (every 15 minutes is standard) and compares Shopify’s numbers against what the external system holds.
Polling catches the events webhooks miss. It is slower — you are limited by Shopify’s default rate limit of 2 REST API calls per second on standard plans — but it provides the safety net that keeps systems aligned over hours and days.
A practical polling schedule for most operations:
- Under 1,000 SKUs: poll every 15 minutes
- 1,000-10,000 SKUs: poll every 30 minutes with delta filtering
- Over 10,000 SKUs: poll hourly, or use GraphQL bulk operations to pull full snapshots
A well-built sync layer uses both: webhooks for speed, polling for correctness.
Multi-location sync complexity
If you are running Shopify multi-location inventory management, sync gets more complex. Each inventory_levels/update event is scoped to a specific location, so your integration needs to track quantities per location, not just per SKU.
A common mistake is treating multi-location inventory as a single pool. When you sync without location context, aggregate quantities can look correct while per-location counts are wrong. A SKU might show 10 units total but have 0 at the fulfillment location that is live for orders.
Shopify supports up to 1,000 locations per store. Each location generates its own webhook events, meaning a single order fulfilled from 3 locations can produce 3 separate inventory_levels/update events within the same second.
What good sync architecture looks like
What are the 4 layers of a reliable Shopify inventory sync?
Teams that get this right build 4 layers into their integration. For teams without the engineering resources to build a custom sync pipeline, Shopify inventory tracking software handles this architecture out of the box:
- Webhook receiver with immediate 200 response: acknowledge the event before processing to prevent Shopify from retrying while you are still working. Target response time under 500 milliseconds.
- Idempotency check: use the webhook ID to skip duplicate events before they touch your database. Store processed IDs for at least 72 hours.
- Event queue: buffer incoming events so bursts (like a flash sale with 100+ simultaneous orders) do not overwhelm your processing pipeline. Tools like Redis, SQS, or RabbitMQ handle this well.
- Reconciliation job: a scheduled pass that queries Shopify’s API directly and flags any discrepancy larger than 0 units between systems. Run this at minimum every 15 minutes.
For teams using Shopify barcode scanning setup to manage warehouse operations, scan-based updates add another source of inventory changes that must flow through the same sync pipeline.
Sync failure detection checklist
When sync breaks, these are the signals to watch:
- Customer-facing stockouts on items your WMS shows as in stock
- Oversells that result in backorders or cancellations
- Quantity differences between Shopify admin and your external system that exceed 1-2 units
- Webhook delivery logs showing repeated 4xx or 5xx responses
- Reconciliation reports flagging the same SKUs repeatedly
Teams processing over 200 orders per day should review reconciliation reports daily. Below that threshold, a weekly review typically catches issues before they compound.
How Upzone handles Shopify inventory sync
Upzone connects to Shopify using a webhook subscription plus a reconciliation layer. Quantity changes made inside Upzone (scan-based receiving, cycle counts, pick confirmations from the Shopify pick pack ship workflow) push to Shopify immediately. Changes that originate in Shopify (orders, manual adjustments) sync back to Upzone through the webhook stream.
The reconciliation pass runs every 15 minutes and logs any discrepancy above 0 units for review. Sync gaps surface in the dashboard before they affect shipments or downstream workflows.
For teams organizing stock at the bin level, warehouse bin locations in Shopify explains how location and bin-level tracking layers onto the sync architecture.
For a full view of how sync fits into the operational setup, the Shopify inventory management guide covers the complete picture.
Quick Reference
- Shopify webhooks deliver inventory events within 1-3 seconds under normal conditions
- Webhook delivery is best-effort; roughly 1-2% of events can be missed, delayed, or duplicated
- Shopify retries failed webhook deliveries for up to 48 hours
- REST API default rate limit is 2 requests/second (40/sec on Shopify Plus)
- Inventory distortion costs retailers $1.77 trillion globally per year (IHL Group, 2024)
- 4 required sync layers: webhook receiver, idempotency check, event queue, reconciliation job
| Sync method | Speed | Reliability | Best for |
|---|---|---|---|
| Webhooks only | 1-3 seconds | ~98-99% (best-effort) | Real-time updates, low volume |
| Polling only | Every 15-60 minutes | High (API-confirmed) | Fallback, audit, reconciliation |
| Webhooks + polling | 1-3 seconds with fallback | High | Production integrations |
| GraphQL bulk operations | Minutes (batch job) | High | Large catalogs (10,000+ SKUs) |
| Manual CSV import | On demand | Manual verification | One-time corrections |
Warehouse execution breaks when Shopify and floor activity drift apart. Start a free Upzone trial to keep products, inventory, orders, and fulfillment in sync.
Start free trial →