skip to content

An async request-reply API can notify completion either by having the client poll a status endpoint, or by having the client register a webhook URL that the server calls back with the result. What are the operational trade-offs between these two delivery mechanisms, and when would you choose one over the other?

level: seniorimportance: should knowfreq 55%

answer

  1. webhook = server calls the client back
  2. polling = client repeatedly asks
  3. webhooks need a public reachable endpoint plus signature verification
  4. at-least-once delivery -> dedupe by job id on the client
  5. hybrid APIs often support both

basics

~20 s

Polling means the client keeps checking back for updates; a callback (webhook) means the server calls the client back when the work is done. Polling is simpler to set up on the client side; callbacks are faster and less wasteful but need the client to run something reachable.

solid answer

~40 s

Polling requires no inbound connectivity from the client and is trivial for browsers and mobile apps, but wastes requests and adds latency up to the poll interval, and its load scales with clients times poll rate. Callbacks eliminate polling overhead and give near-immediate notification, but require the client to expose a publicly reachable, authenticated HTTPS endpoint, handle at-least-once delivery by deduping on job id, and the server must implement retry, backoff, and dead-lettering for failed callback attempts. Server-to-server integrations, like payment providers and CI systems, favor webhooks; user-facing browser or mobile clients favor polling or a push channel like SSE/WebSocket that doesn't require the client to run a server.

go deeper

for a junior

Can describe the basic difference: client asks versus server calls back.

for a middle

Knows browsers and mobile apps typically can't receive webhooks directly and why polling or SSE is used there instead.

for a senior

Discusses webhook signature verification, retry/backoff/dead-lettering, and idempotent handling of duplicate deliveries.

for a principal

Designs the API to offer both mechanisms, sets retry and security conventions reused across the platform, and reasons about cost — infra load from polling versus delivery-guarantee complexity of webhooks — at scale.

## Two ends of a push-versus-pull trade-off Polling and webhook callbacks are the two dominant ways an async request-reply system delivers a completion notification back to the original caller, and they sit at opposite ends of a **push-versus-pull** trade-off. | Aspect | Polling | Webhook callback | |---|---|---| | Who owns the initiative | the client | the server | | Inbound connectivity | zero inbound network configuration on the client's side | the client must run something that accepts inbound HTTPS traffic | | Notification latency | bounded by the poll interval | near-immediate | | Fits | browsers and mobile apps | server-to-server integrations | ## Polling — the client owns the initiative With polling, the client owns the initiative: after receiving 202 and a status URL, it repeatedly issues `GET` requests until it observes a terminal state. This requires zero inbound network configuration on the client's side, which is exactly why it's the default for browsers and mobile apps, both of which typically sit behind NATs, firewalls, or app-store sandboxing that make accepting an inbound connection impractical. The cost is inefficiency: - most polls return 'still running' and are wasted work - notification latency is bounded by the poll interval rather than being immediate - server-side load scales roughly with the number of active clients times their poll frequency, which is exactly the poll-storm failure mode discussed elsewhere in this pattern ## Webhook callbacks — the server owns the initiative With a webhook callback, the server owns the initiative: the client registers a URL when submitting the job, and the server issues an HTTP `POST` to that URL once the job reaches a terminal state, carrying the result or error in the request body. This gives near-immediate notification with no wasted requests, but it inverts the trust and reachability model. The client must run something that accepts inbound HTTPS traffic, which server-to-server integrations can do easily but browser and mobile clients generally cannot. It also introduces a **security surface**: anyone who discovers or guesses the webhook URL could attempt to inject a fake completion event, so the sender must sign each payload, commonly with `HMAC-SHA256` over the raw request body using a shared secret, and the receiver must verify that signature before trusting the content. **Delivery itself is not guaranteed exactly once** over an unreliable network — if the receiver doesn't return a prompt `2xx`, the sender typically retries with exponential backoff over some bounded window, which means the receiving client must treat duplicate deliveries of the same job id as a normal, expected event and process them idempotently rather than as an error condition. If delivery keeps failing, the sender should dead-letter the notification or fall back to making the result available via a pollable status endpoint so the client isn't left permanently stranded. ## Why many APIs offer both Because the two mechanisms fit different network postures, many production APIs offer both rather than forcing one choice on every consumer: a server-to-server integration registers a webhook for low latency, while a CLI tool or script behind a restrictive firewall falls back to polling the same underlying job. - **Stripe** is a widely known example of this dual approach — most integrations subscribe to webhooks for events like payment completion, but the same information is also retrievable by directly polling the relevant resource, which matters when a webhook was missed or arrived out of order. - **GitHub Actions** and many CI/CD platforms similarly expose both a status API to poll and the option to configure a webhook, letting each consumer choose based on its own connectivity constraints and latency requirements. ## Choosing between them in practice Choosing between them in practice comes down to who controls the client's runtime environment and how much latency matters. If the caller is a backend service you don't operate but that can run a stable, publicly reachable listener, webhooks minimize both latency and wasted traffic. If the caller is a browser tab, a mobile app, or an environment behind NAT with no inbound access, polling, or a push channel like Server-Sent Events or WebSockets that the client itself initiates, is the only workable option without extra infrastructure like a message relay.

  • How does a webhook receiver defend against a malicious or buggy caller forging completion notifications?
    The sender signs each webhook payload, commonly with HMAC-SHA256 over the raw body using a shared secret, and includes the signature in a header. The receiver recomputes and compares that signature before trusting the payload, since without it anyone who discovers the webhook URL could inject fake 'job completed' events.
  • What happens if the client's webhook endpoint is down when the server tries to deliver the callback?
    The server should retry with exponential backoff over a bounded window, from minutes up to roughly a day, and if delivery still fails, either dead-letter the notification for alerting and manual follow-up or fall back to a pollable status endpoint so the client can still recover the result on its own.
  • Why might a public API offer both polling and webhooks rather than picking just one?
    Different consumers face different network constraints: a server-to-server integration can expose a webhook endpoint and wants low-latency notification, while a script or CLI tool behind NAT or a firewall can only poll outward. Offering both lets each consumer pick the mechanism that fits its own connectivity posture instead of forcing a one-size-fits-all design.

Polling is calling the restaurant every ten minutes to ask if your takeout is ready; a webhook callback is giving them your phone number so they text you the moment it's ready.

saying these in an interview costs you the question

  • thinks webhooks require no additional security beyond HTTPS
  • doesn't mention at-least-once delivery or idempotent handling on the client side for callbacks
  • assumes polling has zero cost
  • can't explain why browser or mobile clients typically can't receive webhooks directly
  • conflates webhook callback with fire-and-forget pub/sub

context