Problem
On the free Grafana Cloud plan only 14 days of metrics are retained, but the status page presents the 30-day and 1-year windows as fully covered - reporting a confident, false 100% uptime (see #12). The app is read-only and can't recover dropped data, so the fix isn't to recover the missing history; it's to stop presenting windows longer than what's retained as if they're complete. The retention limit varies by plan, so this needs to be configurable rather than hardcoded to 14.
Proposed solution
Make coverage environment-driven and honest, defaulting to today's behavior:
- New config var
METRICS_RETENTION_DAYS in lib/config.ts (server-side, like the other non-branding config). Unset ⇒ unlimited ⇒ no change for existing deployments; set to 14 for the free tier.
- Honest numbers: for any window that exceeds retention, skip the PromQL query and mark uptime/response as insufficient (renders
—) instead of computing a misleading ratio over a partial range. Applies everywhere the per-window figures surface: overview list, per-site uptime grid, and the window selector. Bonus: fewer Grafana queries per refresh.
- Clamp the selected-window charts to the retained span so, e.g., the
1y view shows the ~14 days that actually exist at usable density rather than a near-empty strip.
- Coverage note (a small info banner) explaining, e.g., "Only the last 14 days of monitoring data are retained on this plan — longer windows show what's available."
- Mock data honors the same var so
MOCK=1 METRICS_RETENTION_DAYS=14 reproduces the behavior locally.
Stays stateless and read-only; keeps the windows visible rather than removing features; documented in .env.example, docs/configuration.md, and docs/architecture.md.
Alternatives considered
- Hide the 30d/1y selectors/cards beyond retention — cleaner visually, but removes UI and needs a fallback for existing
?window=1y links; disclosing coverage is more transparent than hiding it.
- Detect the earliest available sample dynamically rather than a config var — more truthful ("data since "), but adds per-check query cost and is fiddly in Prometheus over long ranges. A static, env-driven limit fits the project's stateless, configurable philosophy better.
- Leave PromQL as-is and only annotate — less code, but a 30d figure could still silently equal the 14d figure without saying so; clamping the ranges keeps within-retention numbers computed over real data.
Additional context
Problem
On the free Grafana Cloud plan only 14 days of metrics are retained, but the status page presents the 30-day and 1-year windows as fully covered - reporting a confident, false
100%uptime (see #12). The app is read-only and can't recover dropped data, so the fix isn't to recover the missing history; it's to stop presenting windows longer than what's retained as if they're complete. The retention limit varies by plan, so this needs to be configurable rather than hardcoded to 14.Proposed solution
Make coverage environment-driven and honest, defaulting to today's behavior:
METRICS_RETENTION_DAYSinlib/config.ts(server-side, like the other non-branding config). Unset ⇒ unlimited ⇒ no change for existing deployments; set to14for the free tier.—) instead of computing a misleading ratio over a partial range. Applies everywhere the per-window figures surface: overview list, per-site uptime grid, and the window selector. Bonus: fewer Grafana queries per refresh.1yview shows the ~14 days that actually exist at usable density rather than a near-empty strip.MOCK=1 METRICS_RETENTION_DAYS=14reproduces the behavior locally.Stays stateless and read-only; keeps the windows visible rather than removing features; documented in
.env.example,docs/configuration.md, anddocs/architecture.md.Alternatives considered
?window=1ylinks; disclosing coverage is more transparent than hiding it.Additional context