Skip to content

Status page

The public status page lives at status.persql.com. It’s open to the internet (no login) and refreshes every 30 seconds.

  • An overall operational / degraded / outage badge.
  • 24-hour and last-hour uptime percentages.
  • p50 and p95 probe latency over the last hour.
  • A 24-hour minute-by-minute sparkline. Each cell hovers a tooltip with the timestamp, HTTP status, and round-trip latency.

A synthetic probe runs every minute against the api worker’s /health endpoint via the public hostname (api.persql.com). That exercises:

  • DNS + Cloudflare edge routing.
  • The Worker isolate cold-start path.
  • Fetch → handler → JSON response → fetch resolution.

A 2xx response within 5 seconds counts as healthy. Anything else (non-2xx, transport error, timeout) counts as a failed probe and contributes to a “down” minute on the page.

LevelTrigger
operationalLast 15 minutes have zero failed probes
degradedAny failed probe in the last 15 minutes
outageLast probe failed AND ≥3 of the last 15 failed, or ≥8 of 15 failed

These are heuristics — a single failed probe shows as degraded for ~15 minutes even if everything has fully recovered. We err toward showing problems sooner rather than hiding them.

The same data is available as JSON at /status.json:

Terminal window
curl -sS https://status.persql.com/status.json | jq .data.level
# "operational"

Schema:

interface StatusResponse {
success: true;
data: {
level: "operational" | "degraded" | "outage";
uptime24h: number; // percentage 0–100, one decimal
uptime1h: number;
latencyMsP50: number | null; // null when no healthy samples in the last hour
latencyMsP95: number | null;
lastSampleAt: number | null; // unix-ms of the most recent probe
lastFailureAt: number | null; // unix-ms of the most recent failure (any age)
samples: Array<{
ts: number; // unix-ms of the minute bucket
ms: number; // probe latency in ms; -1 means transport failure
status: number; // HTTP status; 0 means transport failure
}>;
};
}

This is a stable surface — feel free to scrape it from your own monitoring or wire it into PagerDuty / Slack.

  • The probe isn’t running queries against your data. It exercises the api worker; if a single tenant’s DO is unhealthy the page can still be green. For per-database health, run your own probe against /v1/db/:ns/:slug/tables.
  • Buffer is 24 hours. Older history isn’t surfaced — the page is for current status, not long-term reliability reporting.