Skip to main content
Webhooks vs Pollinglesson 3 of 3 · 3 min read

When Polling Is Actually Right

The reputation, and what it costs

Polling has a bad reputation, and naive polling has earned it. Thousands of clients asking every five seconds, 99 percent of the answers empty, and the load scaling with how many clients you have rather than how much is happening.

Weigh that against what a reliable webhook consumer actually costs you: signature checking, async processing, deduplication, a dead letter queue, reconciliation. There are plenty of situations where a polling loop gets the same outcome for a tenth of the work.

Poll when you cannot receive calls at all. A service behind a corporate firewall, a script on a laptop, a mobile app, a batch job with no stable public address.

Poll when the provider has no webhooks, or offers them with no signatures and no retries, in which case their list endpoint is the only interface you can trust.

Poll when freshness barely matters. If a dashboard syncing every 15 minutes is fine, a scheduled job hitting a list-changes endpoint is your entire architecture. No public endpoint to secure and no failed deliveries to chase, because each poll is its own retry.

Polling is more correct for state

Prefer it for keeping state in sync, where it is simply more correct. Webhooks tell you what happened; polling tells you what is.

Notice the asymmetry there. A missed webhook is a permanent gap unless you reconcile it, while a missed poll is corrected by the next poll, because every poll fetches the current state.

That self-healing property is why even heavy webhook users poll underneath, and why the mature answer is both. Webhooks for latency, polling for truth.

Refine it two ways and polling becomes respectable at scale. Ask only for what changed since your last position, which keeps every response small and cheap. And when you need low latency without webhook machinery, hold the request open until data arrives or a timeout passes. That gets you close to push while staying an ordinary HTTP client.

Worked example

Diego's team syncs inventory from a warehouse management system into their storefront. The WMS offers webhooks, but they are unsigned, retry only once, and the WMS vendor's status page shows webhook incidents monthly. Rather than build trust infrastructure on an untrustworthy sender, Diego writes a poller: every 60 seconds it calls the WMS list endpoint with updated_since set to the last watermark, fetching around 200 changed SKUs per cycle out of a 40,000-SKU catalog. The whole integration is 150 lines plus a cron entry, and there is no public endpoint to secure or monitor. When the WMS has a four-hour outage in May, the poller just finds four hours of changes in its next successful cycle and catches up in two polls. Stock levels lag by at most a minute, which merchandising confirmed nobody can perceive. The webhook integration remains unbuilt, deliberately.

Webhooks vs Polling: wrapping up

In the real world

  • 01Stripe signs every webhook with an HMAC-SHA256 Stripe-Signature header, retries failed deliveries with exponential backoff for up to three days, and exposes /v1/events so integrators can poll and reconcile missed deliveries.
  • 02GitHub webhooks must be answered within 10 seconds, and payloads are signed with X-Hub-Signature-256, which is why every CI system's receiver acknowledges first and clones later.
  • 03Shopify retries failed webhook deliveries 19 times over roughly 48 hours and then deletes the subscription entirely, so integrations that stay down too long silently stop receiving events.
  • 04Slack's Events API retries failed deliveries three times and temporarily disables event delivery to apps whose endpoints keep failing, pushing developers toward the fast-ack pattern.
  • 05Zapier historically ran most integrations on polling, hitting APIs on 1-to-15 minute intervals depending on plan, demonstrating that products can be built on polling when providers lack webhooks.

Questions people ask

How do I stop attackers from sending fake webhooks to my endpoint?

Verify the provider's signature on every delivery. Providers like Stripe and GitHub send an HMAC of the payload computed with a shared secret; recompute it over the raw request body and compare before trusting anything. Also check the timestamp included in the signature scheme to reject replayed requests. Treat an unsigned or unverifiable delivery as hostile and return an error without acting on it.

Why should my webhook handler return 200 before processing the event?

Providers time out slow endpoints and count timeouts as failed deliveries, triggering retries that pile onto the same slow handler. Acknowledging after durably storing the event, in a queue or table, keeps your response under a second regardless of processing cost, and moves retries of failed processing into infrastructure you control instead of the provider's schedule.

If webhooks are real-time, why would I still poll?

Because webhooks can be missed, past the retry window, during misconfigurations, or from provider incidents, and a missed webhook is a permanent gap unless something checks. Polling fetches current state, so any single miss is corrected by the next cycle. Mature integrations use both: webhooks for low latency, a periodic reconciliation poll for correctness.

Quick review

Polling:
client calls endpoint repeatedly at fixed interval. Simple but wastes resources when no updates
Short polling:
immediate response (empty or data). Interval typically 5 to 30s. Easy to implement
Long polling:
server holds request open until data arrives or timeout. Better real-time than short poll
Webhook:
server calls YOUR registered HTTP endpoint when event fires. Real-time, efficient
Webhook reliability:
client must be reachable. Provider retries with exponential backoff on non-2xx
Webhook security:
validate HMAC-SHA256 signature header (e.g., Stripe-Signature). Never trust payload alone
Webhook failure handling:
return 2xx immediately, then process async. If processing fails, use your own retry queue
Use case examples:
GitHub webhooks on push, Stripe webhooks on payment, Slack events API
the trade-off

Webhooks: client must be reliably reachable. Polling: wasted resources on empty responses.

in the room

Webhooks for low-to-medium frequency event-driven notifications. Polling when webhook delivery can't be guaranteed.