Matt Scott

Webhooks vs polling for uptime alerts

For programmatic incident consumption, webhooks deliver in about a second. Polling adds an average of half your poll interval on top, pure waiting, after the incident already exists. Here is the real tradeoff, and the failure mode most guides skip.

For programmatic uptime alerts, a webhook puts a confirmed incident in front of your code within about a second of it being created. Polling adds an average of half your poll interval on top of that after the incident already exists, pure waiting, because your code is asking on its own schedule instead of being notified the instant it happens.

Two different things are called "push" here

A monitoring tool already pushes alerts to a human: email, Slack, maybe SMS through a third party. WebPixie does this too, on every plan for email, and on Slack from the Starter plan up, the moment an incident opens. That is push already, not polling, and it is not the comparison this post is making.

Polling only enters the picture once you are building your own integration against a GraphQL API instead of subscribing to a webhook, pulling incident and monitor state on a schedule you control rather than waiting for the provider to tell you. That is the actual decision this post is about: webhook push versus API polling for a program consuming incident data, not which human notification channel to enable.

Detection latency and delivery latency are not the same number

Detection latency is fixed by your check interval, plus any retry logic the monitor runs before it trusts a failure. That part is already spent by the time an incident record exists. Delivery latency is what happens next, and it is the part webhook versus polling actually controls.

A webhook fires almost immediately after the event is created, typically well under a second of transport time. A poll only picks up a new event on its next scheduled run, so on average you wait half the poll interval, and in the worst case the full interval, purely because your code asked at the wrong time.

Poll interval Average added delay Worst-case added delay
Every 15 seconds ~7.5 seconds 15 seconds
Every 60 seconds ~30 seconds 60 seconds
Every 5 minutes ~2.5 minutes 5 minutes
Webhook ~0 (sub-second transport) ~0

That wait buys you nothing. The incident already exists in full, with its severity and affected resource already set when it is created. A tighter poll interval just spends more requests to shrink a delay that a webhook removes entirely.

What actually gets sent

WebPixie opens an incident automatically when a check confirms a real failure, then closes it automatically when the underlying check recovers. Both transitions are webhook-eligible events, alongside the certificate and domain checks that share the same lifecycle:

  • Uptime: incident creation on a confirmed failure, incident closure on recovery.
  • SSL: check failure, plus certificate approaching expiry.
  • Domain: approaching expiry, and entering a suspended or hold state.

Each event carries a severity from INFO through CRITICAL and an occurrence count, so a flapping endpoint arrives as one incident with a rising count instead of a new payload for every blip. Webhooks are available from the Pro plan up; below that, polling the GraphQL API is the only way to consume this programmatically at all, which is its own argument for building the poll fallback regardless of which plan you start on.

The failure mode most guides skip

Every generic webhook-versus-polling comparison mentions that a receiver can go down and miss deliveries. For an uptime alert specifically, that failure is not a minor gap, it is the exact message you built the pipeline to guarantee. If your webhook endpoint is unreachable when your production site goes down, the one delivery you most needed is the one most likely to get lost, because both failures can share a cause: your infrastructure is having a bad day.

Three things reduce this risk without giving up on webhooks: verify the payload signature so a dropped or replayed delivery is at least detectable, key your processing off a stable event identifier so a retried delivery does not double-fire your downstream action, and put the receiving endpoint itself on a monitor separate from whatever it is meant to alert about. That last one sounds circular, and it is, on purpose. An alert pipeline is infrastructure, and infrastructure that only gets checked when it is already needed is exactly the pattern a monitor giving you a false read warns against for the sites themselves.

When polling is still the right call

Polling is not a downgrade, it is the correct choice in a few specific situations:

  • You are below the Pro plan and do not have webhook access yet.
  • Your environment cannot accept inbound HTTPS traffic at all, common behind strict corporate networks or in short-lived CI jobs that have no stable public endpoint to receive a callback.
  • You need full state reconciliation on a schedule regardless of individual events, for example nightly syncing every open incident into an internal dashboard rather than reacting to each one as it happens.

These are not arguments against webhooks; they are reasons polling is the more honest fit for what you are building. Picking a poll interval here is the same tradeoff as picking a check interval: faster costs more requests and gets you closer to real time, slower costs less and accepts a wider blind spot, and there is no universally correct number, only the one that matches how fast you actually need to know.

The pattern most teams land on

Webhook as the fast path, with a periodic GraphQL poll as a reconciliation pass, not a primary channel, catching anything a missed or unverified delivery let through. The poll interval here can be wide, every few minutes is enough for a safety net rather than a real-time feed, because its job is to close gaps, not carry the load.

The version of this that actually works treats the webhook receiver as a piece of production infrastructure from day one: signed, idempotent, and monitored on its own, with polling as the backstop for the day it is not.