Skip to content

[Feature] Make long-window uptime honest about the plan's data retention #13

Description

@maquchizi

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions