Why we poll Shopify instead of using webhooks
Webhooks fail silently and Shopify gives up after about 48 hours. If the receiving end is a desktop that gets switched off, polling's worst case is a late job while a webhook's worst case is a lost one.
Ashraful
Shopify Select Partner
Short answer: use webhooks when the receiving end is a server that is always on and can answer in under five seconds. Use polling when the receiver is a desktop PC, a machine behind a firewall, a laptop someone closes at night, or anything that can be offline for hours. Webhooks fail silently and Shopify gives up after roughly 48 hours. Polling's worst case is a late job; a webhook's worst case is a lost one.
Every integration tutorial starts with webhooks. They are the modern answer, they are event-driven, and they are what the documentation shows you first.
We built an order automation for a print shop and deliberately did not use them.
This is why, and when you should make the same call.
What actually breaks with webhooks?
A webhook is Shopify making an HTTP request to a URL you own when something happens. Order paid, product updated, customer created. Shopify sends it, expects a 200 back within five seconds, and moves on.
Three things about that arrangement matter more than they look.
Your endpoint has to be reachable from the public internet. Not "on the network". Reachable, with a real domain and a valid TLS certificate. A PC in the back of a print shop is not reachable. Making it reachable means a tunnel, a static IP or a relay server, and each of those is another thing that can be down at 2am.
Your endpoint has to answer in five seconds. Not finish the work in five seconds, but acknowledge in five. If the job is downloading a 400MB file, you have to accept the webhook, queue the work, return 200, and process separately. That means you need a queue. The queue needs to survive a restart. You are now maintaining infrastructure that has nothing to do with the problem you set out to solve.
Failures are retried, then dropped. Shopify retries with backoff over roughly 48 hours. After that the event is gone. Not queued, not flagged, not emailed to you. Gone. And if your endpoint fails often enough, Shopify removes the subscription entirely and sends a notification you may not read.
The last one is the real problem. A machine that was switched off over a long weekend comes back to nothing. No error, no gap in a log, no way to know which orders were missed — because the record of them being missed lived in the delivery attempts, and those expired.
What does polling actually cost?
Polling is asking Shopify every N seconds whether anything new has happened.
The objections are usually latency and rate limits. Both are smaller than they sound.
Latency. A 60-second poll means a job starts up to a minute late. For an order landing in a print queue that a person will look at within the hour, one minute is not a number anyone can perceive. For a live inventory display on a storefront, it is. Match the interval to what the delay actually costs.
Rate limits. The Admin API on the REST endpoints gives two requests per second with a burst bucket of 40; GraphQL works on a points-per-second cost model. Polling once a minute with a filtered query spends a rounding error of that. We have never come close on an order poller.
Missed events. Polling does not miss. Ask for orders updated since your last checkpoint, and if you were off for three days you get three days of orders on the next run. Nothing expired, because nothing was being held for you.
That is the whole trade. Polling gives up freshness to gain the guarantee that work is never lost.
Webhooks vs polling, side by side
| Webhooks | Polling | |
|---|---|---|
| Receiver must be public | Yes | No |
| Works behind a firewall | No, needs a tunnel | Yes |
| Survives being offline | Only under ~48 hours | Yes, indefinitely |
| Missed events | Silently dropped after retries | Impossible by design |
| Latency | Seconds | Your interval |
| Needs a queue | Yes, in practice | No |
| Needs TLS and a domain | Yes | No |
| Load on Shopify | Minimal | Small, and predictable |
| Debugging a gap | Delivery log, if not expired | Re-run from the checkpoint |
Webhooks win the top of the table. Polling wins every row about failure.
When each one is right
Use webhooks when the receiver is a cloud service you control and monitor, sub-second reaction genuinely matters, volume is high enough that polling would be wasteful, and you already have a queue and retry handling because the rest of your system needs one.
Use polling when the receiver is a desktop or on-premise machine, the machine is ever switched off, the work per event is heavy, a minute of delay costs nothing, or you want one moving part instead of five.
Use both when you want webhook speed with polling as the safety net. The webhook triggers immediately; a slow poll sweeps for anything the webhook missed. This is the right answer at scale and the wrong answer at the start, because you are now maintaining two paths and the reconciliation between them.
We use polling alone on the print shop build. The RIP machine lives in a workshop, gets switched off, and occasionally loses its internet connection when someone unplugs the wrong thing. There is no version of webhooks that survives that without a relay server, and a relay server is a monthly bill plus a second thing to monitor.
How do you build a poller that does not lose work?
The pattern is short, and almost all of it is about the checkpoint.
Ask for a window, not a list. Query orders updated after your last checkpoint, sorted ascending. Not "the latest 50" — that breaks the moment you are behind by 51.
Write the checkpoint last. Process the order fully, confirm the side effects landed, then advance the checkpoint. If the process dies mid-way, the next run redoes that order. Redoing is recoverable. Skipping is not.
Make the work idempotent. Since a crash means you will reprocess, processing twice has to be harmless. The cheapest way we have found is to write a marker on the record itself — an order tag, a metafield — and check it before starting. The tag is written last, after everything else succeeded, so a half-finished order has no tag and gets picked up again.
Overlap the window slightly. Query from the checkpoint minus a small buffer. Clock skew and write visibility delays are real, and with idempotency in place the overlap costs nothing.
Log the gap, not just the events. Record the time of every successful poll. A missing run is the signal that something was wrong, and it is the only signal you get when the answer was legitimately "nothing new".
Do not trust the poll interval as a heartbeat. If the poller crashes, the polls stop, and silence looks identical to a quiet day. Alert on the absence of a successful poll, not on errors.
That list is roughly 150 lines of code. The webhook equivalent, done to the same reliability standard, is a public endpoint, TLS, signature verification, a durable queue, a retry policy, a dead letter queue and a reconciliation job.
The question that actually decides it
Not "which is more modern". Ask: what happens if the receiving end is off for a week?
If the answer is "we lose orders", you need polling, regardless of what the tutorial says.
If the answer is "the queue holds them and drains when it comes back", you already have the infrastructure webhooks require, and webhooks are the better fit.
Everything else is detail.
We build Shopify integrations that run on the client's own hardware, with no monthly fee and the source code handed over. Deciding between webhooks and polling is the first conversation, and it is usually shorter than people expect.
Got an integration landing on a machine that is not always on? Book a free 30 minute call and describe the setup. Or read how we built an order-to-print-file pipeline using exactly this pattern, or see our app development work.
Frequently asked questions
Should I use Shopify webhooks or polling?
Webhooks if the receiver is an always-on server that can acknowledge in under five seconds. Polling if the receiver is a desktop, an on-premise machine, or anything behind a firewall that can be offline. Webhooks drop events silently after about 48 hours of failed retries; polling cannot miss, because it asks for everything since its last checkpoint.
What happens if a Shopify webhook fails?
Shopify retries with backoff over roughly 48 hours, then discards the event permanently. No notification of the individual loss. If failures continue, Shopify can remove the webhook subscription entirely.
Will polling the Shopify API hit rate limits?
Not at a sensible interval. REST allows two requests per second with a 40-request burst bucket; GraphQL uses a points-per-second model. A filtered order poll once a minute uses a fraction of either. Rate limits become a concern when you poll every second or fetch unfiltered lists.
How often should I poll Shopify for new orders?
Match the interval to what the delay costs. Sixty seconds is right for order-to-production work a human will see within the hour. Fifteen seconds for anything a customer is waiting on. Slower than five minutes and people start to notice.
Can a Shopify webhook reach a computer in my office?
Not directly. It needs a publicly reachable HTTPS URL, which means a tunnel, static IP or relay server. That is another piece of infrastructure to pay for and monitor. Polling from the machine outward needs none of it and works through any firewall that allows outbound HTTPS.
How do I avoid processing the same Shopify order twice?
Write a marker on the order itself — a tag or metafield — as the final step, after all the real work has succeeded, and check for it before starting. A half-finished order has no marker and is safely picked up on the next run.
Can I use webhooks and polling together?
Yes, and it is the right pattern at scale: the webhook fires immediately, a slow poll sweeps for anything it missed. The cost is two code paths and reconciliation logic between them, which is rarely worth it before you have a reliability problem to solve.
About the author
Ashraful
Shopify Select Partner, Top Rated Plus on Upwork. 700+ Shopify projects shipped over 7+ years: themes, apps, migrations, speed, Hydrogen. Solo shop, no agency middlemen.
Read the full storyWorking on a Shopify project?
That's what I do every day. Pick whichever feels lower-friction.
More from the blog
Keep reading
Shopify automation with no hosting and no monthly fee
The monthly fee in most integration quotes is hosting, and hosting exists to accept inbound connections. Reverse the direction and the entire category of cost disappears.
ReadLetting customers upload files on a Shopify product page
Shopify's cart supports file attachments natively and almost nobody knows it. It is free, it works, and it stops at 20MB, which is exactly where print work begins.
ReadUsing Shopify order tags as a job ledger
Write the tag last, check it first, make every side effect repeatable. Three sentences that replace a database for once-per-order automation, and keep the work queue visible in the Shopify admin.
Read