API integration comparison
Webhook vs Polling
The classic push vs pull debate in API integration. Webhooks push events to you instantly; polling asks repeatedly. The right choice depends on your latency needs, infrastructure constraints, and the reliability guarantees you need.
TL;DR
- Webhook — event-driven push. The source server calls your endpoint when something happens. Near-instant, efficient, but your endpoint must be publicly reachable.
- Polling — scheduled pull. Your client asks "anything new?" at regular intervals. Works from anywhere, simple to implement, but wastes resources and has up-to-interval latency.
- Default to webhooks for external integrations where the source supports them. Use polling as a fallback, for simple cases, or when you operate behind a firewall.
Side-by-side comparison
| Aspect | Webhook | Polling |
|---|---|---|
| Direction | Push — server calls your endpoint | Pull — your client calls server |
| Latency | Milliseconds — event-driven | Up to full poll interval |
| Server load | Low — only calls when events occur | Higher — constant requests even when nothing changed |
| Reliability | Depends on retry mechanism of source | Client controls — always gets current state on request |
| Implementation | Expose a public HTTPS endpoint | A scheduled job or loop calling an API |
| Firewall friendliness | Requires public endpoint (inbound) | Works anywhere (outbound only) |
| Debugging | Harder — events arrive asynchronously | Easier — deterministic, inspectable |
| Best for | Payment events, CI/CD triggers, third-party SaaS | Simple scripts, behind-firewall services, reconciliation |
Code side-by-side
Getting notified when a GitHub PR is merged:
Webhook (Express handler)
// GitHub calls this URL on PR merge
app.post('/webhooks/github', (req, res) => {
const sig = req.headers['x-hub-signature-256'];
if (!verifySignature(sig, req.body)) {
return res.status(401).send('Unauthorized');
}
const { action, pull_request } = req.body;
if (action === 'closed' && pull_request.merged) {
triggerDeploy(pull_request.head.sha);
}
res.status(200).send('OK');
}); Polling (cron every 60 s)
// Runs every minute — checks for merged PRs
async function pollMergedPRs() {
const prs = await github.pulls.list({
owner: 'acme', repo: 'app',
state: 'closed',
sort: 'updated',
per_page: 10,
});
for (const pr of prs.data) {
if (pr.merged_at && !seen.has(pr.id)) {
seen.add(pr.id);
triggerDeploy(pr.merge_commit_sha);
}
}
}
setInterval(pollMergedPRs, 60_000); When to use Webhooks
- Payment providers. Stripe, PayPal, and Adyen push payment events (succeeded, failed, refunded) seconds after they occur — too important to delay by a polling interval.
- CI/CD triggers. GitHub, GitLab, and Bitbucket push repository events (push, PR merge) to your build system instantly via webhooks.
- Third-party SaaS integrations. CRM, support tools, and e-commerce platforms all offer webhooks for real-time event delivery.
- High event volume with sparse changes. If events are rare but time-sensitive, constant polling wastes resources; a webhook delivers exactly when needed.
When to use Polling
- Behind-firewall services. Internal tools that cannot expose a public endpoint must poll outbound APIs.
- Sources that do not support webhooks. Many older APIs, FTP-based data feeds, or database change feeds require polling.
- Periodic reconciliation. Even with webhooks, you should periodically poll to catch any missed events and reconcile your state with the source of truth.
- Simple scripts and one-off tasks. A cron job polling an API is far simpler to implement and operate than a webhook endpoint with signature verification and retry handling.
English phrases engineers use
Webhook conversations
- "Register a webhook endpoint in the Stripe dashboard."
- "Always verify the signature to reject forged requests."
- "Make the handler idempotent — Stripe may retry on timeout."
- "Return 200 OK immediately and process in the background."
- "Check the webhook logs in the provider dashboard for failed deliveries."
Polling conversations
- "We poll the API every 30 seconds for new orders."
- "Use a since parameter (last seen timestamp) to avoid re-fetching old records."
- "Aggressive polling is hitting our rate limits — back off to 5 minutes."
- "We use ETag / If-None-Match so the server returns 304 when nothing changed."
- "Polling is our fallback for webhook failures."
Quick decision tree
- Source supports webhooks, endpoint is public → Webhook
- Service is behind a firewall / private VPC → Polling
- Need sub-second event latency → Webhook
- Simple cron script, no infrastructure to expose → Polling
- Payment / security-critical events → Webhook + periodic reconciliation polling
- Source does not offer webhooks → Polling
- Many events expected but changes are rare → Webhook (polling wastes resources)
Frequently asked questions
What is a webhook?
A webhook is an HTTP callback. When an event occurs in system A, it sends an HTTP POST request to a URL you configure on system B. The event is pushed to you immediately — you do not have to ask. Examples: GitHub sends a webhook when a commit is pushed; Stripe sends a webhook when a payment succeeds.
What is polling?
Polling is when your client repeatedly asks a server "has anything changed?" at regular intervals — every 5 seconds, every minute, every hour. If there is new data, you get it; if not, you get an empty response and wait until the next poll.
Which has lower latency?
Webhooks have much lower latency. You are notified within milliseconds of the event. Polling latency equals up to the full polling interval — if you poll every 60 seconds, you may wait up to 60 seconds to learn about an event. Reducing the interval improves latency but increases server load.
What happens if my webhook endpoint is down?
Good webhook providers (Stripe, GitHub) retry with exponential backoff for several hours and have a dead-letter mechanism. However, if you miss the retry window, events can be lost. You should implement idempotent handlers and, for critical data, periodically reconcile with the source of truth via a polling/fetch call.
Are webhooks friendly to firewalls?
This is the main limitation of webhooks. Your endpoint must be publicly reachable — which can be a problem for services behind a corporate firewall, a private VPC, or a local development machine. Polling works from anywhere because it is the client that initiates the outbound connection.
What is long polling?
Long polling is a technique where the client makes a request and the server holds it open until there is data to return (or a timeout). When the response arrives the client immediately makes another request. It bridges the latency gap between regular polling and webhooks, but at the cost of holding open connections. WebSockets and Server-Sent Events are generally better modern alternatives.