Skip to content

What do you need to do?

Docs

Probe methodology

Honesty is the product, so here is exactly how a check runs: where it probes from, how often, how long it waits, how many failures it takes before something is called down, and where our own detection is deliberately biased and what that bias costs you.

Regions

Your own checks (HTTP, TCP, DNS, SMTP, and Ping) run from ten regions: US-East, US-West, Europe, Asia-Pacific, US-Central, Canada, UK, Southeast Asia, Australia, and South America. You pick which of those regions probe a given check when you create it, all ten by default. Heartbeat monitors have no region: nothing reaches out for them. The Monitor agent runs from wherever you install it, in addition to any cloud regions bound to the same check. See Checks & monitors for the full region and interval picture, including the Monitor agent's own rules.

The public outage tracker is a separate product from your own checks, sharing the same prober code but watching third-party services rather than anything you own. See its own methodology page for that product's specifics.

Cadence per tier

A check's interval is set once, at creation, and never changes on its own after that: upgrading or downgrading your plan does not rewrite an existing check's interval, only the floor offered to new ones. The floor itself is defined by tier in TIER_MIN_INTERVAL_SECONDS, in packages/db/checks.ts, the one place this number lives; quoting the seconds here would let this page drift the moment that table changes, so read the constant if you need the exact current value for every plan. As of this writing: Free and Growth run as fast as 60 seconds, Scale (and MSP, which includes everything in Scale) as fast as 30 seconds.

The public outage tracker's catalog runs on its own, separate cadence ladder (fast, standard, and slow tiers, defined as CATALOG_CADENCE_SECONDS in packages/db/outage-catalog.ts) chosen per service by how often that service actually has incidents, not by anyone's subscription. It has nothing to do with your own check intervals above.

Timeouts

A single HTTP probe attempt has a 10-second timeout, and that budget resets on each redirect hop it follows (redirects are never auto-followed by the underlying fetch; each hop is independently validated and re-pinned to a safe address before it is taken). A probe is bounded end to end by a hard wall-clock deadline of the per-hop timeout multiplied by the maximum number of hops it can take, so a target that strings together several slow redirects cannot run indefinitely. The exact numbers (the per-hop timeout and the hop limit) live in packages/checker/index.ts, and the deadline mechanism that enforces the total budget lives in packages/checker/probe-deadline.ts. A probe that blows its budget is recorded as a normal failed check, not a crash: it is reported the same way a connection refusal is, just with a timeout as the reason.

Before something is called down

One failed probe in a region does not make that region down. Each region keeps its own consecutive failure count, and only flips from operational to down after two consecutive failures; one success is enough to flip it back. That hysteresis exists so a single transient blip, a dropped packet, a momentary blip on our side, does not read as an outage. This decision is pure and unit-tested on its own (computeRegionTransition in packages/db/index.ts), independent of anything else on the page.

Rather than wait out that region's full interval for the second, confirming probe, an unconfirmed first failure schedules a fast re-check five seconds later, so confirmation (or a recovery) usually lands in seconds, not minutes. That delay is a fixed constant in packages/checker/index.ts, alongside a cap on how many fast re-checks can be in flight at once: past that cap a confirmation is shed and simply falls back to the check's normal interval, logged so the shed is a visible fact rather than a silent slowdown.

A confirmed region-down transition is one more step from paging anyone. Alert rules can require a minimum number of regions to be confirmed down at once (min_failing_regions, default 1) before operator channels (Slack, operator email, PagerDuty, webhooks) fire; this quorum stacks on top of, never instead of, each region's own two-failure confirmation. It only silences operator paging, never the public status page or subscriber notifications, which follow the region transition exactly as before, so what your customers are told never depends on how you have your own paging tuned. The full rule, including how quorum pairs a down transition with its matching recovery, is in packages/db/alert-quorum.ts.

Vocabulary

A single region is always one of three states: operational, down (two confirmed failures, as above), or briefly recovering back through operational on the next success. Nothing in a single region is ever "degraded"; degraded is a property of the check as a whole, once you look across every region it runs from:

  • Operational. Every region that has reported is operational.
  • Degraded. At least one region is down and at least one is still operational, a partial, regional failure rather than a total one.
  • Down. Every region that has reported is down.
  • Unknown. No region has ever reported a result for this check yet, a brand-new check or one with no history, not a claim about its health either way.
  • Stale. Every region that reported is either unreported or old: a region's last result stops counting as fresh once it is more than three times the region's interval old, so a probe fleet that has stopped reaching a check does not keep showing its last, possibly outdated, reading as current.

This is the one aggregation rule, defined once (aggregateStatus and its staleness-aware counterpart in packages/db/index.ts) and read everywhere it is shown: your dashboard, the public status page, and the public API all report the identical thing because they all call the same function rather than each re-deriving it.

The public outage tracker's catalog uses one more word, blocked, that never appears for your own checks. See the false-positive section below for what it means and why it exists only there.

The false-positive trade-off

Your own checks and the public outage tracker optimize for opposite failure modes, on purpose, because the cost of being wrong points in opposite directions for each.

A check you own is watching your own service. Missing a real problem (a false negative) costs you a customer finding out before you do; a false alarm costs you a notification you can dismiss in seconds. Given that asymmetry, your checks resolve every failure to a plain down once confirmed: a timeout, a connection refusal, a 5xx, a failed response assertion, all become down with no separate "maybe it's not really down" bucket. The cost of this choice is real and worth naming: if your own WAF, CDN, or bot-defense layer ever blocks our probe's requests specifically, whether by IP reputation, a missing browser fingerprint, or a stricter rate limit, that reads as your service being down, even though a real visitor would have gotten through. That is the trade you are making by using us to watch your own infrastructure: fewer missed outages, at the cost of occasionally chasing a false alarm caused by your own front door being pickier than it is with real traffic.

The outage tracker watches services we do not own, and publishing a false "down" claim about someone else's service is the one thing that product cannot afford to get wrong: it damages a vendor we have no relationship with and undermines every other reading on the page. So its classifier (classifyCatalogObservation in packages/db/outage-results.ts) reserves "down" for failure modes a real user would actually experience (refused or reset connections, DNS failure, TLS failure, a 5xx, or a genuinely user-experienceable timeout) and files everything that looks like our own probe being singled out under "blocked" instead: an HTTP 403, 406, 429, or 451, a redirect loop that only an automated, datacenter-sourced client would ever hit, or a hang with no corroborating evidence that the service itself is actually broken.

That last rule changed on 2026-08-27 (REA-346) after an audit of the catalog found a bare timeout, with zero HTTP response ever received, was the single largest source of false "down" claims in the whole catalog: 47% of every down reading across 2,117 probes was exactly this, including services that were never actually down, just consistently slower to respond than our timeout. A hang by itself is symmetric evidence: it is equally explained by "the service is down" and by "something between us and the service ate our request," and a datacenter-sourced prober cannot tell those apart from the hang alone. So a hang now only becomes "down" when a second, independent endpoint for the same service answered with an actual unhealthy status in the same round, positive evidence something is really broken; a hang with no such evidence, including a sibling endpoint that hung the identical way, is filed as "blocked," not down. The full rule, including the exact bot-defense status codes and the reasoning behind each one, is documented in that module.

We never let a vendor's own claimed status override what we actually observed; their own status feed is shown as side-by-side context, never a rewrite of our reading. Both products' rules govern only what we classify from what we ourselves saw.