Webhook or polling trigger: which should you use?
The webhook-vs-polling decision is not about latency, it is about who is responsible for recovering events when your automation is down. A webhook hands that job to the source, whose retry policy ranges from Stripe's three days to GitHub's none, while a polling trigger asks the source what changed since the last check and dedupes by ID, so downtime costs latency, not data.
When an app offers both an instant trigger and a polling trigger, most operators pick instant and assume it is strictly better. It is not. The real question is not which is faster, it is who is responsible for recovering events when your automation is down. A webhook hands that job to the source, and source retry policies range from generous to nonexistent: Stripe retries a failed delivery for about three days, Shopify retries roughly eight times over four hours and then deletes your subscription, and GitHub does not retry at all. A polling trigger keeps that job for itself. It asks the source what changed since the last check and dedupes by record ID, so an hour of downtime costs you latency, never data.
The whole industry frames this comparison as latency versus API calls. That framing is fine for a systems-design interview and useless for an operator deciding which trigger to click. You will almost never lose money because an order synced two minutes late. You will lose money the day your endpoint is unreachable for an hour and the events that arrived during that hour are simply gone, with nothing in any log to tell you they ever existed. That risk is the decision. Here is how to make it.
Why the real axis is recovery, not latency
A webhook delivers in seconds. A polling trigger delivers on its interval, usually one to fifteen minutes depending on your plan. For the large majority of business workflows, the difference between "two seconds" and "four minutes" changes nothing. A lead that lands in the CRM four minutes later still gets called. A nightly invoice sync does not care.
What actually separates the two is what happens during failure. Both triggers work perfectly when everything is up. The question is what each does when your automation is not listening: a deploy, an expired credential, a platform incident, a self-hosted box that rebooted. With polling, you find out about the gap on the next successful poll and the backlog flows in. With a webhook, the source already tried to reach you, and what it did when it could not is entirely the source's call, not yours.
What happens to a webhook when you are not listening
The source decides, and the policies are all over the map. This is the table nobody puts in front of you before you click "instant trigger," and it is the heart of the decision.
| Source | If your endpoint is down or errors | Retry window | When it gives up |
|---|---|---|---|
| Stripe | Retries with exponential backoff (5 min, 30 min, 2 h, 5 h, 10 h, then hourly) | About 16 attempts over roughly 3 days | Marks the event permanently failed; you can resend from the dashboard |
| Shopify | Retries on a backoff schedule | About 8 attempts over 4 hours | Removes the webhook subscription entirely, so future events are not even sent |
| GitHub | Does not retry automatically | None | You must redeliver manually or by script, only within the last 3 days |
| Generic SaaS or webhook node | Often one attempt, no retry | Usually none | The event is gone the moment the single delivery fails |
Two rows on this table should change how you build. Shopify does not just stop retrying after four hours, it deletes the subscription. New orders after that point are never sent to you at all, and there is no error and no run to alert on, because the platform on your end is simply never contacted. This is the textbook case of an automation that silently stops, the kind covered in why automations silently break, and the only thing that catches it is the inverted monitoring described in how to get alerted when an automation stops running.
The GitHub row is the other trap. No automatic retry means a single failed delivery is a lost event unless you wrote a reconciliation job that polls the deliveries API and resends the failures. If you took the instant trigger to avoid building anything, GitHub just handed you a polling job anyway, except now it is one you have to maintain yourself.
Why a polling trigger structurally cannot miss
A polling trigger asks a different question. Instead of waiting to be told, it periodically asks the source: give me everything that changed since the last time I asked. The source returns the new and updated records, and the platform dedupes them by unique ID so the same record never fires the workflow twice. Zapier documents exactly this: it compares each record's ID against IDs it has already seen and runs only on genuinely new ones.
The consequence is the whole point. If your automation is down for an hour, the next poll asks the same question and gets back everything created during that hour. Nothing is dropped, because nothing was ever pushed to a door that was locked. You traded a few minutes of latency for a trigger that recovers itself with no work from you. There is exactly one way a polling trigger misses: pagination. If a source creates more new records between two polls than a single poll returns, the oldest can fall off the end of the page. The fix is to poll more often or raise the per-poll limit, and it only bites high-volume sources.
Polling has a real cost, and it is honesty to name it: it consumes operations on every check even when nothing changed. On a per-execution or per-task billing model that adds up, which is the other half of the trigger decision and is covered in our piece on what an AI automation costs per month. A webhook only runs when there is something to do. For a low-frequency, high-stakes event, that efficiency can matter. For most flows, the operations cost of a ten-minute poll is noise.
How your automation platform changes the math
The source is only half the story. Your platform decides what happens to a webhook event the instant it arrives, and the three common tools behave very differently.
| Platform | Webhook behavior on arrival | What this means for downtime |
|---|---|---|
| n8n | The Webhook node accepts the POST and runs immediately; there is no inbound queue | If the instance is down, the source gets no acknowledgment and recovery is 100 percent the source's retry policy. A Schedule trigger does not backfill missed ticks, but a scheduled poll that queries "since last run" by timestamp does catch up, because you control the query |
| Zapier | Instant triggers are REST-hook webhooks; polling triggers run every 1 to 15 minutes by plan with built-in dedup | Polling Zaps recover backlogs automatically. For instant Zaps, recovery depends on whether the source app retries |
| Make | Webhooks write into an inbound queue that holds events even while the scenario is off, up to roughly 667 items per 10,000 monthly operations | A Make webhook does not drop events during short downtime the way an n8n webhook can, until the queue overflows its limit |
This is the nuance that flips a lot of advice. "Use a webhook" is much safer on Make than on raw n8n, because Make buffers inbound events and n8n does not. On n8n, a webhook is only as reliable as the upstream source's willingness to retry, so pairing an n8n webhook with a generous source like Stripe is fine, while pairing it with a fire-and-forget source is asking to lose events on your next deploy.
The decision rule
Stop asking which is faster. Ask these in order:
- Do I need the result within seconds, with a human or system waiting on it? If no, poll. It is simpler, it cannot miss, and you own recovery. This covers most syncs, enrichments, and reports.
- If yes, does the source retry failed deliveries for hours or days? If yes (Stripe-like), use the webhook and make your handler idempotent, because a forgiving source will redeliver the same event many times. Dedupe by event ID and use an idempotency key on any write that charges or emails, the same discipline laid out in when an automation should retry.
- If you need speed but the source is fire-and-forget (GitHub-like or a generic API)? Use the webhook for the fast path and add a low-frequency polling reconciliation as a safety net. That hybrid is the only honest way to get both low latency and no lost events from a source that will not retry.
- Is the event money or otherwise irreversible? Then dedupe by ID no matter which trigger you chose, because both a redelivered webhook and a polling catch-up will present the same record more than once. The cost of getting this wrong is a double charge, not a late sync.
For irreversible work, latency is the cheap problem and duplication is the expensive one. Optimize accordingly.
What to do next
Take your single most important automation and look up one fact you almost certainly do not know: its source's webhook retry policy. Not a guess, the actual documented behavior. If the source retries for days, an idempotent webhook is a fine choice. If it retries for four hours and then deletes your subscription, or does not retry at all, either switch that trigger to polling or add a polling reconciliation behind the webhook, and put a heartbeat on it so a silent stop pages you instead of surprising a customer.
This trigger choice is one of the first decisions we lock down when we build a system, because it determines whether the whole thing survives a bad afternoon. If you want triggers chosen for recoverability rather than for whichever option had the lightning-bolt icon, that is the foundation of our workflow automation systems. Or send us the automation you would least like to lose events from, and we will tell you exactly where it is fragile and how to harden it.
Frequently Asked Questions
SOURCES & CITATIONS
- Manage event destinations (webhook retries) — Stripe Documentationhttps://docs.stripe.com/workbench/event-destinations
- Troubleshoot webhooks — Shopify Developer Documentationhttps://shopify.dev/docs/apps/build/webhooks/troubleshooting-webhooks
- Handling failed webhook deliveries — GitHub Docshttps://docs.github.com/en/webhooks/using-webhooks/handling-failed-webhook-deliveries
- How Zap triggers work — Zapier Help Centerhttps://help.zapier.com/hc/en-us/articles/8496244568589-How-Zap-triggers-work
About Alexey Yushkin
Alexey is the founder of GENERAL INFORMATICS LLC. He designs and ships AI and automation systems for businesses and operators across the US.
Related reading
Want this kind of system in your business?
We build practical AI and automation systems for operators. Send us your current workflow and we will show you what to automate first.
Request a Workflow Review