How Shopify Webhook Retries Break in Production (2026)
No7 Engineering Team
Growth Architecture Unit

Relying on raw webhooks for transactional ecommerce workflows guarantees data loss during traffic spikes. Shopify webhook retries attempt delivery up to eight times over four hours with a strict five-second timeout before silently disabling the subscription. If your endpoint executes synchronous database operations or third-party API calls before returning a 200 OK, you will lose orders.
Delivery Mechanisms Compared: Webhooks, Polling, and Flow
Shopify provides three distinct mechanisms to synchronise data with external systems, each built with different operational guarantees and failure modes. Webhooks deliver real-time notifications for discrete events, GraphQL bulk queries extract high-volume datasets asynchronously, and Shopify Flow automates internal business logic without custom server infrastructure.
| Mechanism | Delivery Guarantee | Latency Profile | Failure Behaviour | Best For |
|---|---|---|---|---|
| Shopify Webhooks | At-least-once (unordered) | Near real-time (sub-second) | 8 retries over 4 hours, then dropped | Instant order routing, 3PL dispatch, inventory events |
| GraphQL Bulk Operations | Exact query snapshot | Minutes to hours (asynchronous) | Job fails, requires query retry | Nightly ERP syncs, catalogue exports, reconciliation |
| Shopify Flow Triggers | Managed internal execution | Near real-time (1-5 seconds) | Workflow run status logged in admin | Internal tagging, customer segmentation, basic alerts |
Choose Shopify webhooks when downstream systems must react immediately to customer actions, such as capturing a fraud risk score or reserving 3PL inventory. Choose GraphQL bulk polling when you need complete consistency across thousands of records without risking dropped payloads. Choose Shopify Flow when logic can remain entirely within the Shopify admin boundaries.
How the Shopify Webhook Delivery and Retry Schedule Works
Shopify delivers webhook payloads via HTTPS POST requests and requires your endpoint to return any HTTP 2xx status code within a strict five-second timeout window. If your endpoint returns a non-2xx status code or exceeds five seconds, Shopify marks the delivery attempt as failed and begins its exponential backoff schedule.
As documented in the official Shopify webhook documentation, the platform retries failed deliveries up to eight times over approximately four hours. The delay between consecutive attempts increases with each failure. If your service remains unreachable or slow across all eight attempts, Shopify marks the subscription as failing and permanently deletes the webhook subscription.
This automatic deletion happens silently. Shopify does not send an email alert or dashboard warning when a subscription is purged. New store events stop emitting payloads entirely until your team re-registers the subscription. On three Shopify Plus ERP integrations we shipped, webhook subscription deletion was the root cause behind intermittent missing orders during maintenance windows.
Verifying Webhook HMAC Signatures Without Body Parser Bugs
Every webhook request from Shopify includes an X-Shopify-Hmac-SHA256 header containing a Base64-encoded SHA-256 hash generated with your app secret. Verifying this signature is mandatory for security, but common web server middleware frequently corrupts the validation process.
The hash calculation must run against the exact raw byte buffer of the incoming HTTP request body. If middleware such as Express body-parser or Next.js body parsers parse the payload into JSON before the HMAC check runs, key reordering, whitespace normalization, and UTF-8 encoding differences will alter the string. The calculated signature will not match Shopify header value.
If the calculated HMAC does not match the header, your server must immediately return a standard 401 Unauthorized status. Always verify signatures using a constant-time comparison function like crypto.timingSafeEqual in Node.js to protect your endpoints against timing attacks.
Handling at-Least-Once Delivery and Out-of-Order Payloads
Shopify guarantees at-least-once delivery, which means your application will receive duplicate payloads for the same event during network retries or infrastructure rebalancing. Shopify also does not guarantee ordered delivery across multiple events on the same resource.
Duplicate deliveries occur frequently when your server processes a request successfully but the HTTP response takes 5.1 seconds to reach Shopify edge proxy. Shopify records a timeout and retries, delivering the exact same payload a second time. To prevent duplicate order creation or double billing, extract the X-Shopify-Webhook-Id header and store it in an in-memory cache such as Redis with a 48-hour TTL. If the ID exists in cache, return 200 OK immediately and drop the duplicate.
Out-of-order delivery creates severe data corruption if unmanaged. For instance, an orders/updated webhook triggered by a customer address update can arrive at your server before the original orders/create webhook. If your handler assumes the order record already exists in your local database, the update fails. Use SQL upserts or version check columns against the payload updated_at timestamp to ensure older payloads never overwrite fresher data.
Production Webhook Architecture Checklist
- Raw Buffer Ingestion: Capture incoming request bodies as raw byte buffers before applying any JSON parsing middleware.
- Sub-100ms Acknowledgement: Verify HMAC, push the raw payload and headers to a message broker, and return 200 OK within 100ms.
- Idempotency Layer: Store the
X-Shopify-Webhook-Idin Redis with a 48-hour expiration to drop duplicate deliveries safely. - Timestamp Comparison: Compare the payload
updated_atagainst local database state to reject stale out-of-order events. - Dead Letter Queue (DLQ): Route permanently failed background worker jobs to a DLQ with payload context for manual replay.
- Subscription Health Monitoring: Run a scheduled daily query against the Shopify GraphQL API to verify active subscriptions exist.
Why Do Shopify Webhooks Fail in High-Volume Production?
The primary reason Shopify webhooks fail under heavy load is synchronous work blocking the HTTP handler past the five-second cutoff. When hundreds of webhooks arrive simultaneously during a flash sale or catalogue import, database connection pools exhaust and external API calls slow down.
Serverless cold starts also introduce latency spikes. If your webhook endpoint runs on AWS Lambda or Google Cloud Functions without provisioned concurrency, a cold start spinning up container runtime and establishing database connections can take four to six seconds. Shopify triggers a retry before your code even executes.
Managing API version lifecycles is another critical failure point. In the Shopify webhooks API, subscriptions configure an api_version such as 2026-04. Shopify deprecates API versions quarterly. When an old API version reaches end-of-life, payload structures can change or deprecated Shopify webhook topics can stop delivering events without explicit code errors.
Ingestion Architecture for High-Volume Shopify Webhooks
The standard pattern for production-grade reliability separates webhook ingestion from payload processing. The HTTP ingestion server performs only two tasks: verifying the HMAC signature and pushing the raw payload into a durable message queue like Amazon SQS, RabbitMQ, or Redis BullMQ.
In our integration audits, moving payload processing from the HTTP handler into a background Redis queue cut webhook timeout failure rates to zero. The ingestion endpoint consistently responds in under 50ms, safely beneath the five-second deadline. Background worker processes pull messages from the queue at a controlled rate, respecting downstream database write locks and third-party rate limits.
When a worker fails to process a job due to downstream service downtime, your queue handles internal exponential backoff independently of Shopify retry schedule. If a message fails all internal retry attempts, move it to a Dead Letter Queue (DLQ) alongside the original error stack trace and headers. This preserves the event for inspection and manual replay once the downstream issue is resolved.
Automated Reconciliation Patterns for Lost Payloads
Even with an optimised ingestion pipeline, network partitions or third-party outages can still result in missed events. A production architecture must include automated reconciliation to catch records that failed before reaching your queue or were purged during sustained outages.
Rather than relying entirely on real-time pushes, run a scheduled polling job every few hours using the Shopify GraphQL Admin API to query resources updated within a sliding time window. For high-volume catalogues, execute bulk queries that stream JSONL files directly from cloud storage, bypassing API rate limit buckets entirely.
Reconciliation jobs compare Shopify current state against your local database or ERP, backfilling missing records and fixing drift caused by dropped events. Pairing event-driven webhooks with state-based reconciliation gives you both sub-second dispatch and guaranteed consistency.
Next Steps for Securing Your Production Pipeline
Audit your existing webhook handlers to identify any synchronous database queries, email dispatches, or external API calls executing before the HTTP response returns. Decouple these operations into an asynchronous background queue immediately.
Implement a daily verification script that queries your registered Shopify webhook topics via GraphQL to ensure no subscriptions were quietly deleted following transient network hiccups. Combine these Shopify webhook best practices with scheduled reconciliation to ensure zero lost transactions. For complex enterprise stores connecting Shopify Plus to NetSuite, SAP, or custom warehousing systems, explore our dedicated Shopify integrations engineering services to build resilient, fault-tolerant data pipelines.
Frequently Asked Questions
The questions buyers and engineers ask us most about this topic.
What causes Shopify webhook retries to fail permanently?
Shopify permanently drops webhook deliveries when an endpoint fails eight consecutive times over approximately four hours. Failures occur when the server returns a non-2xx HTTP code or exceeds the strict five-second timeout window. After sustained failures, Shopify silently removes the webhook subscription without sending an alert.
How should I handle Shopify webhook idempotency in production?
Extract the unique X-Shopify-Webhook-Id header from each incoming request and store it in an in-memory database like Redis with a 48-hour TTL. If an incoming webhook contains an ID that already exists in cache, acknowledge the request with an immediate 200 OK and discard the duplicate payload.
When should I choose polling over Shopify webhooks?
Webhooks are ideal for real-time, event-driven tasks like order fulfillment and inventory reservation. Polling via GraphQL Bulk Operations is preferred for large batch synchronisations, nightly catalogue exports, and automated reconciliation jobs where complete dataset consistency matters more than sub-second latency.