How we measure
Every number on this site comes from probes we operate ourselves. No provider feeds us data. No status-page scraping inflates any uptime figure. This page explains exactly what we measure, how we turn raw observations into a "service was up at minute N" verdict, and how those verdicts compose into the rankings on the home page.
This page is our public commitment about how the system works. The numbers behind every ranking are exposed via our read-only API, so any figure on the site is reproducible by anyone with an HTTP client. If something here looks wrong, tell us — hello [at] uptimeproject [dot] org .
Probes
Cadence
Consensus
License
The probe network
We run five probe agents on geographically and network-diverse infrastructure across four cloud providers. Vultr Seattle and Vultr Singapore share a provider — a deliberate trade-off favouring an Asia-Pacific vantage point over a fifth distinct provider at a less-useful location. Probes ship their observations to our ingest endpoint over a private overlay network, not via the public internet.
| Provider | Location |
|---|---|
| Hetzner | Falkenstein, DE |
| OVH | Roubaix, FR |
| DigitalOcean | New York, US |
| Vultr | Seattle, US |
| Vultr | Singapore, SG |
Critical rules. Every probe monitors every service — the variance across vantage points is the data. We never run a probe on the infrastructure of a provider we measure: there is no AWS probe measuring AWS, no GCP probe measuring GCP, no Cloudflare probe measuring Cloudflare. A probe inside a measured provider's network would have a structurally favourable path that distorts the comparison, so we do not have one.
Five probes is the minimum size at which our strict-majority consensus rule (below) can still produce a verdict when one probe is down for maintenance. We plan to grow the fleet to seven over time — adding two, not five, because diminishing returns on geographic diversity kick in fast once you have one probe per continent.
Check types
Each service is monitored by one or more checks. The check type determines what is measured; the per-check interval determines how often. The probe fires each check on a deterministic per-check offset within its interval window — so the fleet does not synchronise outbound traffic against any single target, even when many services share the same upstream provider.
| Type | What it measures | Cadence | Timeout |
|---|---|---|---|
| HTTP | Per-phase timing (DNS, TCP connect, TLS handshake, time-to-first-byte, total). HTTP responses with a defined status code (2xx, 3xx, 4xx) are recorded as success; 5xx and network-level errors are recorded as failure. | 60 s | 30 s |
| DNS | Recursive query to an explicit resolver (default 1.1.1.1:53) with optional expected-RDATA match. Bypasses the OS resolver entirely. | 300 s | 10 s |
| TCP | Raw TCP connection establishment time to a host:port. Used where HTTP is not the right surface. Not currently exercised by the v1 service registry; supported by the probe binary for future additions. | operator-configurable | operator-configurable |
| TLS | Full TLS handshake + certificate-chain validation + optional days-until-expiry threshold. In the current registry every TLS check carries a 14-day expiry threshold so we get a warning lead time on cert rotation. | 3600 s | 30 s |
| Storage | HTTPS GET against a published test object. Validates SHA-256 body hash and Content-Type. Catches silent corruption, not just connectivity. | 300 – 600 s | 90 s |
HTTP status classification. Responses in 2xx, 3xx, and 4xx are recorded as success. A 4xx response means the server is reachable, processed our request, and returned a defined HTTP status — that is the signal we care about for uptime measurement. 5xx and network-level errors (DNS failure, connection refused, timeout, TLS error) are recorded as failure.
Redirect handling. HTTP checks do not follow redirects. A 301 or 302 IS a valid response and we record the status code we were given. Following redirects would also make the per-phase timing meaningless because each round trip resets the timer.
Authoritative DNS providers. For managed authoritative-DNS services (e.g. AWS Route 53, Google Cloud DNS) we do not use the dns check type. Those products do not run public recursive resolvers — they answer zone-delegated queries — so a recursive query to 1.1.1.1 would measure 1.1.1.1's cache 95% of the time, not the provider. Instead we measure their public control-plane API endpoint over HTTP and TLS. Public recursive resolvers (Cloudflare 1.1.1.1, Quad9, Google Public DNS) are measured directly via the dns check type because the resolver IS the product surface.
From measurement to status
Every probe-check fire produces one row in our raw measurements table. To turn those rows into a public-facing "is this service up?" verdict, we aggregate in two stages: per-probe vote inside each minute, then cross-probe consensus.
Step 1 — per-probe vote inside a minute
A service typically has 2–4 checks (HTTP, TLS handshake, maybe DNS or storage). Inside any one-minute window, a probe is counted as having voted "up" for the service if at least one of its checks for that service succeeded in that minute. This is deliberately generous — the question at this layer is "is the service reachable from this vantage point?", not "is every monitored aspect of it perfect?". The latency and per-check granularity is captured elsewhere.
Step 2 — cross-probe consensus
Once each probe has voted up or down for the minute, we apply a single consensus rule:
Strict majority of reporting probes succeeded (success_count > probe_count / 2).
At least one probe succeeded, but not a majority. Includes 50/50 ties.
Zero of the reporting probes succeeded.
Fewer than three probes reported in the minute. Excluded from availability calculations.
"Strict majority" matters. With four reporting probes a clean 2-of-4 tie counts as degraded, not up — calling a service "up" when half the probes saw it as down would undermine the entire argument of this page. The table below shows how the rule plays out at each likely fleet size:
| Probes reporting | Rule |
|---|---|
| < 3 reporting | — (insufficient signal) |
| 3 reporting | success_count = 0 → down; ≥ 2 → up; else degraded |
| 4 reporting | success_count = 0 → down; ≥ 3 → up; else degraded |
| 5 reporting | success_count = 0 → down; ≥ 3 → up; else degraded |
| 7 reporting (post-expansion) | success_count = 0 → down; ≥ 4 → up; else degraded |
Why < 3 is "unknown". With only one or two probes reporting in a minute, a single false negative on a flaky network would flip the verdict. Three independent probes is the smallest number that still survives one probe being down for maintenance and one false negative without the result becoming arbitrary. "Unknown" minutes are excluded from the availability denominator (see below) so they neither artificially inflate nor depress a service's score.
Availability calculation and ranking
Availability percentage for any window is:
Unknown minutes are excluded from both numerator and denominator. If a window contains only unknown minutes (e.g. a new service in its first hour), the availability is reported as no data rather than 0% or 100% — both would be misleading. The number of unknown minutes is reported separately as a coverage signal, so callers who care about under-measurement can see it.
Availability is reported to two decimal places. At a daily granularity that is the smallest meaningful resolution — one single down-minute in a 1440-minute day already rounds to 99.93%, so finer precision would be noise.
Ranking. The leaderboard sorts services by average availability over the selected window (7 days, 30 days, or 90 days; 30 days is the default), descending. Services with identical availability are tied — we break ties alphabetically by service name, never by a secondary metric. A service with no data in the selected window sorts below everything else and is shown with a "no data yet" treatment rather than being hidden.
What the percentage actually means. A monthly 99.9% rating allows roughly 43 minutes of cumulative downtime in a 30-day window; 99.99% allows about 4 minutes 19 seconds. For the rest of the story — how vendors define their own denominators, why the headline number rarely captures the operational tax of an incident, and what to look at instead — see What 99.99% uptime actually buys you.
Tier 1 vs Tier 2 — what feeds the leaderboard
We separate the data we collect into two tiers that are stored, queried, and ranked independently. Everything described in this page above — probe checks, consensus, availability percentages, the leaderboard — is Tier 1 only. Tier 2 exists in parallel as a sidecar, never as a ranking input.
- Tier 1 — independent measurement. Our own probe fleet, the rules above, the
measurements_rawhypertable and everything aggregated from it. This is the only data that drives the public leaderboard, category pages, and per-service availability numbers. It is the project's reason to exist. - Tier 2 — vendor status pages. What the provider says about itself. Scraped on a 5-minute schedule from
each service's public status page (the URL listed in our service registry),
parsed into a normalised severity vocabulary (operational, minor, major,
critical, maintenance, unknown), and written to a separate hypertable
(
status_page_observations) with explicit provenance: which adapter parsed it, whether the fetch succeeded, what the vendor banner said, how long the fetch took. No view, materialised or otherwise, joins this table with Tier 1 data for ranking purposes.
Why the separation matters. Status pages are structurally biased — a vendor publishing "100% uptime" on a public dashboard during a customer-facing incident has financial reasons to do so (SLA credits) and is, by definition, the entity with the lowest incentive to be honest about its own product. Mingling Tier 2 numbers into Tier 1 averages would let the vendor's editorial decision quietly re-weight our ranking. Keeping them in separate tables makes the comparison the editorial product: "they reported 99.99%, we measured 99.87%" is exactly the kind of signal a reader cannot get from the vendor's own dashboard, and it stays useful only as long as the two numbers are computed independently.
Tier 2 coverage is partial by design. Vendors who run their status page
on Atlassian Statuspage (the de facto industry standard) are parsed today
through a single adapter that hits each page's
/api/v2/status.json endpoint. Vendors
on AWS Health, Google Cloud's incidents.json, Azure's RSS feed, and a handful
of vendor-specific formats are recorded as observations with adapter
none until their dedicated parsers
land — so a gap in our Tier 2 coverage is itself visible as a time-series,
not as a silent missing row. Any Tier 2 figure displayed on the site is
labelled as such; the leaderboard never shows one.
What we do not measure
We measure external reachability from our probe vantage points. That is the entire promise of the headline rankings.
We do not measure provider-internal signals: queue depth, compute capacity, error rates inside a provider's own infrastructure, or anything else a provider does not expose to external clients. A service can be reachable from our probes but slow, and we record that as latency percentiles separately from availability. A provider's internal incident that does not affect external API responses will not appear in our data — by design, because that is the line between "uptime as the user experiences it" and "uptime as the provider's internal dashboards see it".
We never use provider-supplied data in the headline rankings. We do ingest provider status-page banners into a separate Tier 2 table as an editorial cross-check (see Tier 1 vs Tier 2), but that data never mingles with Tier 1 measurements and any Tier 2 figure shown on the site is labelled as such.
Data retention and freshness
- Raw measurements are kept for 90 days, compressed after 7 days. After 90 days the raw chunks are dropped — by then, every minute and day they contain has been folded into the aggregates below.
- Per-minute consensus (service_minute_status) is materialised as a TimescaleDB continuous aggregate, refreshed every minute with a 10-minute look-back to fold in any late-arriving probe batches. Retained indefinitely.
- Per-day availability (service_daily_uptime) is refreshed hourly at minute 5 from the per-minute aggregate. Retained indefinitely.
- Public leaderboard hydrates from the public API on every page load (refresh = fresh numbers, capped by the API's 5-minute edge-cache TTL). End-to-end staleness is at most ~1 hour for the leaderboard (driven by the daily-aggregate's hourly refresh), ~1 minute for any individual service's current-status badge.
- Timestamps on the site and via the API are UTC. Minute and day buckets are aligned to UTC, not to any local time zone.
Independence and conflicts of interest
UptimeProject has no commercial relationships with any measured provider. No provider pays for inclusion, position, or favourable treatment. No provider gets advance notice of incidents we detect.
Where affiliate links appear, they are standard consumer-side referral commissions that exist independently of our measurements and do not influence ranking, inclusion, or anything else observable on this site. Ranking is a deterministic function of the measurement data using the formula defined above — no editorial weighting, no manual promotion, no exceptions for sponsored services.
The service registry — which services we monitor and with what checks — is version-controlled with timestamped, justified commits. We do not currently publish that history, but we will produce a registry-change record for any specific service on request.
Verify our claims
This page is the authoritative description of how UptimeProject measures, classifies, and ranks. The numbers behind every leaderboard entry are exposed via our public read-only API. Browse the interactive reference at /docs/api/ or fetch the raw OpenAPI document at api.uptimeproject.org/v1/openapi.json.
If a published figure looks wrong, query the API for the underlying minute and daily aggregates over the same window and reproduce the calculation defined in "Availability calculation" above. If they don't match, tell us — corrections are public.
Frequently asked
Why is HTTP 4xx treated as success?
A 4xx response means the server is reachable, processed our request, and returned a defined HTTP status. That is the signal "the service is up" — whether the response is what a particular client wanted is application-layer, not uptime. Treating 4xx as failure would mean a public uptime score depends on a probe being authorised to call every endpoint it measures, which is neither realistic nor methodologically clean. 5xx and network errors stay failures because they mean the server did not finish handling the request.
Why "1-minute buckets" and not 10 seconds or 1 hour?
One minute is the smallest bucket where the median check has fired from every probe at least once (60 s default check interval, 5 probes, deterministic per-check jitter spreads them across the window). Shorter buckets would have systematic gaps where "unknown" dominated. Longer buckets would hide brief incidents — a 90-second outage spread across two adjacent minutes shows up as two degraded minutes, which a 1-hour bucket would round to a single non-event.
Why do "unknown" minutes get excluded from the availability denominator?
Unknown means we did not measure the service reliably in that minute — usually because fewer than three of our probes reported. Counting unknown as "up" would inflate availability with minutes we cannot defend. Counting it as "down" would penalise services for gaps in our own probe coverage, which is unfair. Excluding it is the only honest choice; the count of unknown minutes is reported separately as a transparency signal.
Why might a provider show 100% on their own status page while we report less?
Provider status pages report on the internal state of provider-owned systems. We report on external reachability from independent vantage points. Both can be technically correct: a regional fibre cut between Roubaix and the provider has zero internal signal but a real impact on our Roubaix probe. Conversely, an internal incident that does not reach the customer surface will not appear in our data. We measure what users experience.
How often does the leaderboard update?
Per-minute consensus refreshes every minute. The daily availability table refreshes hourly at minute 5 (TimescaleDB continuous aggregates + a regular materialized view). The static site itself hydrates against the public API on every page load — a browser refresh re-fetches the leaderboard with at most ~5 minutes of edge-cache TTL between you and the database. End-to-end, the public leaderboard is at most ~1 hour behind real-time (driven by the daily-aggregate refresh, not the website cadence).
A service was added recently and shows "no data yet". When will it have a ranking?
Services need at least one complete daily bucket (00:00–23:59 UTC) before they have a 1-day availability number, and 30 daily buckets for a 30-day ranking. New services are included in the registry immediately and appear in the leaderboard with a "no data yet" placeholder; the ranking populates as data accumulates.
Why aren't there AWS, GCP, or Azure probes?
We never measure a provider from its own infrastructure. A probe on AWS measuring AWS would have a structurally favourable network path that no AWS competitor enjoys, which would corrupt the comparison. Our probes therefore run only on providers that are not in our measurement set.
Can I get the raw measurements?
Yes. The public API at api.uptimeproject.org exposes per-minute consensus and per-day availability. Per-minute and per-day aggregates are retained indefinitely, but the public API caps responses to the trailing 90-day window for cost and cache reasons; older history is available on request. The OpenAPI spec is linked in the footer. Raw per-probe per-check rows are not currently public — they are retained internally for 90 days for our own analysis. If you have a research use case, write to us.
Data license
All measurement data published on this site and via the public API is licensed under CC BY 4.0. You can use, share, and build on it for any purpose, including commercial, with attribution to UptimeProject and a link back to this methodology page.
Questions, corrections, research collaboration? hello [at] uptimeproject [dot] org