Webhooks or Polling: Which Should Your Automation Use?
Webhooks or Polling: Which Should Your Automation Use?
Use webhooks when the event matters within seconds and you can host a reliable endpoint. Use polling when you cannot, when the source system is unreliable, or when missing an event is worse than acting slowly. Most real systems end up using both, and the interesting work is deciding which does what.
The choice gets made badly because it gets made early, usually by whoever wires the first integration. Then it never gets revisited, and two years later nobody can explain why the CRM sync runs every fifteen minutes while the form handler fires instantly.
Here is how we think about it, with the actual delivery rules from two systems we integrate with constantly.
What Is the Difference Between a Webhook and Polling?
A webhook is push. The source system sends you an HTTP POST the moment something happens, and you react. Polling is pull. You ask the source system on a schedule whether anything changed, and it answers. One is a doorbell. The other is opening the door every ten minutes to check.
The consequences follow from that. Webhooks are near instant and cheap when idle, because nothing happens until something happens. Polling has a built-in delay equal to your interval, and it costs API calls whether or not anything changed.
The less obvious difference is who owns reliability. With a webhook, the sender decides how hard to try and for how long. With polling, you decide. That single fact explains most of what follows.
How Do Webhooks Fail in Practice?
Quietly, and usually at the worst moment. Your endpoint returns a 500 during a deploy. The sender retries a few times, gives up, and the event is gone. Nothing in your system knows it was supposed to receive anything, so there is no error to see and no queue to drain.
Three specific traps catch teams repeatedly. Redirects count as failures, so moving your endpoint and leaving a 301 behind breaks delivery silently. TLS problems break it too. And slow handlers time out, because senders expect an answer before you finish your work, not after.
Stripe's guidance is explicit about that last one. It says your endpoint must quickly return a successful 2xx status code before any complex logic that could cause a timeout, giving the example that you should return a 200 before updating a customer's invoice as paid in your accounting system.
What Do Real Webhook Retry Rules Look Like?
They vary more than people expect, and the difference decides how much you can rely on them. Stripe attempts delivery for up to three days with exponential backoff in live mode. Events created in a sandbox get three retries over a few hours. That is a generous window by any standard.
Webflow is tighter. Its documentation states that a failed delivery is retried up to three more times, at ten minute intervals, and it expects a 200 response to count as success. A deploy that takes your endpoint down for an hour can therefore lose Webflow events permanently.
Stripe also allows manual recovery, which most systems do not. You can resend an event from the Dashboard for up to 15 days after it was created, or via the Stripe CLI for up to 30 days. Knowing which of these your sources offer is the difference between a recoverable incident and a data gap.
Are There Limits on How Many Webhooks You Can Register?
Yes, and they are lower than most integration plans assume. Stripe lets you register up to 16 webhook endpoints. Webflow allows up to 75 webhooks per trigger type, across 14 trigger types including form_submission, site_publish, collection_item_created, collection_item_changed, and ecomm_new_order.
Those numbers shape architecture. With 16 endpoints, you cannot give every internal service its own Stripe subscription, so you need one endpoint that receives many event types and fans them out internally. Stripe supports exactly that, and recommends subscribing only to the event types your integration needs rather than listening to everything.
The Webflow limit is generous per trigger but easy to hit accidentally, because every test integration anyone ever wired up is still registered. Auditing the list is a five minute job nobody does. Our Webflow webhooks guide walks through managing them properly.
When Is Polling Actually the Better Choice?
When correctness matters more than speed. A poll that asks for everything changed since the last successful run cannot lose an event, because the next run picks up whatever the last one missed. Downtime delays the data. It does not destroy it.
Polling also wins when you cannot host a public endpoint. Plenty of internal tools sit behind a VPN with no inbound route, and standing up a public listener just to receive events adds a security surface for very little gain.
And it wins when the source system has no webhooks at all, which is most of the long tail. A spreadsheet, a legacy database, an FTP drop: none of them will ever call you. We covered that end of the stack in our piece on automating web workflows with Zapier and Make.
Which Should You Pick for a Given Job?
Match the mechanism to the cost of being late against the cost of being wrong. If a delay of ten minutes is invisible to the business, polling is simpler and more robust. If the delay is visible to a customer, you want push, with a polling safety net underneath it.
| Factor | Webhooks | Polling |
|---|---|---|
| Latency | Seconds | As long as your interval |
| Cost when idle | Near zero | API calls on every run |
| If your service is down | Event may be lost for good | Caught up on the next run |
| Who controls retries | The sender | You |
| Needs a public endpoint | Yes | No |
| Duplicate deliveries | Expected, must be handled | Rare, but possible on overlap |
The pattern we reach for most often is a hybrid. Webhooks handle the live path so the experience feels instant, and a nightly poll reconciles anything the webhooks dropped. That second job is boring, cheap, and the reason nobody has to explain a missing record on a Monday.
How Do You Make a Webhook Endpoint Safe?
Verify every request before you act on it. Without verification, anyone who learns your URL can post fake events to trigger fulfilment, grant access, or change records. Both systems here sign their payloads, and checking that signature is not optional.
Stripe signs with an HMAC using SHA-256 and sends it in a Stripe-Signature header containing a timestamp and one or more signatures. Its libraries apply a default tolerance of five minutes between that timestamp and the current time, which is what blocks replay attacks. Stripe also supports IP allowlisting and requires TLS 1.2 or 1.3.
Webflow uses the same shape with different names, sending an x-webflow-timestamp header and an x-webflow-signature containing a SHA-256 HMAC. Compare signatures in constant time, and never trust a payload that fails verification, even if it looks correct.
How Do You Stop Duplicate Events Breaking Things?
Assume duplicates will arrive and make your handler idempotent. Stripe states plainly that endpoints might occasionally receive the same event more than once, and recommends logging the event IDs you have processed and skipping ones already logged. That is the whole fix, and it takes one table.
Ordering is the related trap. Stripe does not guarantee events arrive in the order they were generated, and warns against using the created timestamp to determine order or to detect duplicates, because distinct events can share a second. Track IDs instead, and fetch the current object from the API when you need the latest state.
Design handlers so that running twice is harmless. Set a field to a value rather than incrementing it. Upsert rather than insert. When that is impossible, our notes on handling failure in AI automations cover the queue and dead-letter patterns that catch the rest.
What Would We Build for a Typical B2B Site?
Webhooks for anything a human is waiting on, polling for anything a report depends on. A form submission fires a webhook because a salesperson should see the lead now. A CMS sync runs on a schedule because nobody notices if the case study index updates at 2am instead of 1.55am.
Then add three cheap safeguards: log every inbound event with its ID before processing, return a 2xx immediately and do the work on a queue, and run a reconciliation job at least daily. Those three turn a fragile integration into one you can deploy through without holding your breath.
If you are wiring this up and want a second opinion on where the gaps are, we are happy to look. We build these integrations for B2B teams every week at phoenix.studio, and the reconciliation job is almost always the piece that is missing.
Want a site that performs like this?
Tell us about your project. We will come back with a clear next step, no pressure.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
Have a project like this?
Tell us where you want to go. We'll tell you how we'd get you there.