Platform operators

System health

Platform operatorsSystem health

The system health page is at https://booking.netwit.ca/admin/system. It answers one question fast: is the platform up right now? Use it during an incident, when you are about to push a migration, or when a customer reports a weird behavior.

What the page actually checks

The current build calls a single endpoint, GET /api/admin/system/health, and renders a pass/fail row per backing service. The endpoint returns one row each for D1 and KV, plus an overall ok boolean. If any check fails, the endpoint returns HTTP 503 (not 200), and the page banner turns red.

What's wired up vs. on the roadmap.
Today the API returns only D1 and KV. The console page advertises those two. Queue depth, worker latency, and Cloudflare incident status are on the roadmap and are surfaced in this page once the corresponding API endpoints ship. Sections below are marked [roadmap] if they describe work that is not yet in the current build.

Live: D1 health

Probes the primary D1 database by issuing a SELECT COUNT(*) FROM tenants. The console renders:

  • Pass/fail — pass if the query returns, fail if it throws or times out.
  • Detail string"tenants table OK (124 rows)" on pass, or the exception message on fail.

There is no latency number, no error rate, and no per-table breakdown yet. The single check is intentionally cheap; we don't want the health endpoint to itself become a load source on a degraded database.

Live: KV health

Probes the KV namespace by reading the key __healthz__. We never write to it, so the read returns either null ("empty") or some value if a future test seeded it. The check is pass/fail only; there is no latency, no hit-rate, and no key-count surface yet.

[Roadmap] Queue health

BookFlow has three Cloudflare Queues bound in wrangler.toml: bookflow-email, bookflow-sms, and bookflow-webhooks. The admin health page does not yet poll queue depth. The CF dashboard does. If you suspect a backlog:

  • Open the Cloudflare dashboard → Workers → Queues.
  • Check "Messages in flight" and "Oldest message age" per queue.
  • If a queue has >1000 messages in flight or an oldest message >10 minutes old, it's degraded.

[Roadmap] Worker health

Request rate, p50/p95/p99 latency for the API worker are pulled from Cloudflare Workers Analytics. The admin page does not yet call the CF Analytics API directly. The data is in the Cloudflare dashboard under Workers → bookflow-api → Metrics.

[Roadmap] Cloudflare status

Cloudflare publishes its own incident feed at https://www.cloudflarestatus.com. The admin health page does not yet embed this. Subscribe there directly to get incident notifications; we mirror the feed to #platform-oncall in Slack.

Response shape

{
  "data": {
    "overall": true,
    "checks": [
      { "name": "D1", "ok": true, "detail": "tenants table OK (124 rows)" },
      { "name": "KV", "ok": true, "detail": "empty" }
    ],
    "timestamp": "2026-07-25T18:11:00.123Z"
  }
}

HTTP status: 200 if overall = true, 503 otherwise.

Field reference

overallboolean

True if every check passed. False if any check failed.

checks[].namestring

Either "D1" or "KV" in the current build.

checks[].okboolean

True if the probe succeeded.

checks[].detailstring

Human-readable detail. On pass: row counts or "empty". On fail: the exception message.

timestampISO-8601 string

Server time the probe ran.

Alerts and thresholds

The admin page is human-facing. The actual alerting is currently minimal:

  • Cloudflare Workers Analytics — visible in the Cloudflare dashboard under the bookflow-api worker. No automated alerting is configured yet; check it manually when investigating an incident.
  • Email notifications from Cloudflare — if a Worker or D1 is failing at high enough rate, Cloudflare sends an email to the account owner. These land in the same inbox as customer support.

Synthetic monitoring and proper alerting (PagerDuty / Better Stack) are planned but not yet wired up. Until they are, incidents are usually caught by a customer email or by the team noticing the dashboard is slow.

Runbook: what to do when a check is red

D1 red

  1. Open the Cloudflare dashboard → D1 → bookflow → Metrics. Check for "5xx" errors and elevated query duration.
  2. If the dashboard shows nothing, the issue is likely the API worker, not D1. Jump to the worker runbook.
  3. If the dashboard shows errors, check the most recent migration. A bad migration is the #1 cause of D1 red.
  4. Roll back the migration if it was within the last 30 minutes: wrangler d1 migrations apply bookflow --env production --direction down (you need the down migration in the file).
  5. Page the database lead if you can't roll back in 15 minutes.

KV red

  1. Open the Cloudflare dashboard → Workers → KV. Check the namespace's read latency and error rate.
  2. KV is used for sessions, rate-limit buckets, and small caches. A KV outage means customers can't log in or the API is rate-limiting everyone.
  3. There is no failover. Wait for Cloudflare to fix it. Email affected tenants with a status update.

API

GET/api/admin/system/health

Runs a cheap probe against D1 and KV. 200 if all pass, 503 if any fail.

Sample call

curl -i https://booking-api.netwit.ca/api/admin/system/health \
  -H "Authorization: Bearer $ADMIN_TOKEN"

Sample response

HTTP/2 200
content-type: application/json

{
  "data": {
    "overall": true,
    "checks": [
      { "name": "D1", "ok": true, "detail": "tenants table OK (124 rows)" },
      { "name": "KV", "ok": true, "detail": "empty" }
    ],
    "timestamp": "2026-07-25T18:11:00.123Z"
  }
}

Sample 503 (D1 down)

HTTP/2 503
content-type: application/json

{
  "data": {
    "overall": false,
    "checks": [
      { "name": "D1", "ok": false, "detail": "D1_TIMEOUT: Request timed out" },
      { "name": "KV", "ok": true, "detail": "empty" }
    ],
    "timestamp": "2026-07-25T18:11:00.123Z"
  }
}

Quick links

Need a human?

Email hello@netwit.ca or call +1-604-206-8169. NetWit responds in 1 business day.