Making Shopify Webhooks Reliable

Webhooks are how Shopify tells your systems that something happened, an order was placed, a product changed, a customer was created. They are essential for real-time integrations and quietly unreliable if you treat them naively. Building on the assumption that every webhook arrives once, on time, is how integrations silently lose data. Here is how to do it properly.

Webhooks are not guaranteed

Shopify delivers webhooks on a best-effort basis. They can be delayed, delivered more than once, or missed entirely if your endpoint is slow, errors, or is briefly down. Any system that assumes exactly-once, in-order delivery will eventually drop or double-process events. Design for the messy reality instead.

Verify and respond fast

First, verify the HMAC signature so you only act on genuine Shopify events. Then respond quickly, Shopify expects a fast 200, and does the real work asynchronously. If you process heavy logic before responding, you risk timeouts that make Shopify retry and pile up duplicates.

Queue the work

The reliable pattern is: receive, verify, enqueue, respond 200, then process from the queue. A queue absorbs spikes, isolates failures, and lets you retry a failed job without losing the event. This decoupling is the single most important design choice for webhook reliability.

Make handlers idempotent

Because duplicates happen, processing the same webhook twice must be safe. Key work on the event or resource ID so reprocessing an order-created event does not create two orders downstream. Idempotency is the same discipline that makes migrations and inventory syncs safe, and it applies here too.

Reconcile to catch what slips

Even with all of the above, assume some events are missed. Periodically reconcile against the Shopify API, pull recent orders or changes and compare to what you processed, to catch and backfill gaps. Webhooks for speed, reconciliation for completeness, is the robust combination.

Reliable webhook handling is what separates an integration that works in a demo from one that survives production traffic. It underpins the custom apps and integrations we build.