Metric · Observability

What is uptime, and how do you measure it in Metabase?

Uptime is the percentage of time a service was up over a window — the time-based reliability number that ends up in SLAs, status pages, and board decks. Its real value is as a budget: 99.9% is 43.8 downtime minutes a month to spend. Measure it in Metabase from synthetic check results synced from UptimeRobot, Better Stack, or Checkly.

Uptime vs. availability — uptime is time-based (up-minutes ÷ total minutes, usually from probes); service availability is request-based (successful ÷ total requests). This page covers the time-based, SLA-facing number; for the user-experience view, see the availability page.

What uptime measures

It measures the share of the window during which the service answered — and, read as a budget, how much downtime you have left before breaking a promise. The nines translate to fixed allowances: 99.5% is about 3.6 hours a month, 99.9% is 43.8 minutes, 99.99% is 4.4 minutes. That translation is what makes uptime the executive metric: a single number per service per month, comparable across quarters, with an explicit rule for whether announced maintenance windows count. Probes tell you the service was reachable; whether individual requests succeeded is availability's job.

What data does it need?

  • A check_results table: monitor_name, checked_at, is_up, and an is_maintenance_window flag — one row per synthetic check at a constant interval.
  • An incidents table with started_at / resolved_at and a planned_maintenance flag, for minute-accurate downtime per outage.
  • Source: UptimeRobot, Better Stack, or Checkly check exports via Airbyte or the warehouse; Prometheus blackbox-exporter probe results work too.

SQL patterns

Monthly uptime percentage from synthetic checksPostgreSQL
SELECT
  monitor_name,
  date_trunc('month', checked_at) AS month,
  ROUND(
    100.0 * COUNT(*) FILTER (WHERE is_up)
    / NULLIF(COUNT(*), 0), 3
  ) AS uptime_pct,
  COUNT(*) FILTER (WHERE NOT is_up) AS failed_checks
FROM check_results
WHERE NOT is_maintenance_window
GROUP BY 1, 2
ORDER BY 1, 2;
Downtime minutes per incidentPostgreSQL
SELECT
  i.incident_key,
  i.service_name,
  i.severity,
  ROUND(
    EXTRACT(EPOCH FROM (i.resolved_at - i.started_at)) / 60
  ) AS downtime_minutes,
  COUNT(c.checked_at) FILTER (WHERE NOT c.is_up) AS failed_checks
FROM incidents i
LEFT JOIN check_results c
  ON c.monitor_name = i.service_name
  AND c.checked_at BETWEEN i.started_at AND i.resolved_at
WHERE i.resolved_at IS NOT NULL
  AND NOT i.planned_maintenance
  AND i.started_at >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY 1, 2, 3, i.started_at, i.resolved_at
ORDER BY downtime_minutes DESC;

Pitfalls

Quoting a percentage without a window.→ 99.9% over a day allows 1.4 minutes down; over a year, 8 hours 46 minutes. Every uptime number needs its measurement window attached — monthly is the convention because SLA credits are monthly.
Excluding maintenance silently.→ Subtracting maintenance windows without disclosure turns 99.5% into a published 99.95%. Flag maintenance in the data and show raw and adjusted uptime side by side.
Letting the check interval hide short outages.→ A 5-minute probe interval can miss a 4-minute outage entirely — or round a 90-second blip up to 5 minutes of downtime. Match the interval to the precision your target implies; 99.99% is unmeasurable with coarse probes.
Treating a green probe as a healthy service.→ A ping endpoint can answer while checkout fails for a third of users. Probe-based uptime needs request-based availability and error rate next to it before anyone calls the service healthy.

Where this metric applies

Metrics

Dashboards

FAQ

What does 99.9% uptime actually allow?
About 43.8 minutes of downtime per month, or 8 hours 46 minutes per year. Each extra nine divides the budget by ten: 99.99% leaves roughly 4.4 minutes a month, and 99.999% about 26 seconds. Translating the percentage into minutes is the whole point of the executive view — a quarter that "hit 99.9%" and a quarter that burned 40 of its 43 minutes read very differently on a downtime dashboard, and the budget framing is what connects uptime to SLO compliance.
Is uptime the same as availability?
They're siblings, not synonyms. Uptime is time-based: up-minutes over total minutes, usually from synthetic probes. Service availability is request-based: successful requests over total requests. A service can be "up" for the probe while failing a third of real traffic, and a low-traffic service can post ugly request numbers from a single bad minute. Report uptime as the external, contract-facing number and request-based availability as the user-experience number — same family, different denominators.
Should planned maintenance count against uptime?
Decide once, write it down, and encode it as a flag in the data. Most public SLAs exclude announced maintenance windows, which is defensible — but only if the exclusion is visible, because silently subtracting maintenance is how 99.5% gets reported as 99.95%. Keep an is_maintenance_window column in check_results, publish both the raw and adjusted numbers on the uptime dashboard, and let the incident count catch "maintenance" that was really an outage with a calendar invite.
How do you calculate uptime percentage?
Up-time over total time per window: with synthetic checks, COUNT(*) FILTER (WHERE is_up) / COUNT(*) per monitor per month approximates it well when the check interval is constant. For minute-accurate math, sum incident durations instead — total minutes minus downtime minutes, divided by total minutes. Always attach the window: 99.9% over a day, a month, and a year are three different promises, and monthly is the usual reporting grain because it matches SLA credit periods.
How do you track uptime in Metabase?
Sync check results from UptimeRobot, Better Stack, or Checkly into a SQL database via Airbyte or scheduled exports — Metabase reads the warehouse, not the monitoring API. Model one row per check with monitor_name, checked_at, is_up, and a maintenance flag, chart monthly uptime per monitor, and pair it with downtime minutes per incident so the percentage and the human-time cost sit on the same uptime dashboard. It slots into the broader observability analytics stack alongside availability and SLO views.