Skip to content

fix(metrics): cap label cardinality — drop per-user views, *_created, raw-path leak - #179

Merged
VortexUK merged 1 commit into
mainfrom
fix/metrics-cardinality
Jul 25, 2026
Merged

fix(metrics): cap label cardinality — drop per-user views, *_created, raw-path leak#179
VortexUK merged 1 commit into
mainfrom
fix/metrics-cardinality

Conversation

@VortexUK

Copy link
Copy Markdown
Owner

Summary

Grafana Cloud free tier (10k active series) was blown out at 14.5k+. Cardinality dashboard breakdown:

  • user_page_views_total + _created twin = 12,905 series (88%)username (286 values) × path. Dropped entirely (metric, middleware, and the three dashboard panels that read it).
  • disable_created_metrics() — the OpenMetrics *_created companion series doubled every counter/histogram and nothing read them (all flagged "Unused").
  • http_request_duration_seconds: method label removed (no dashboard query used it) + buckets 10 → 6 — ~1,260 series → ~450. http_requests_total unchanged.
  • Hardening against the next blowout: requests matching no route (bot POST probes) collapse to a single (unmatched) path label instead of minting a permanent series per raw URL; scanner verbs (PROPFIND, …) collapse to OTHER; /class-icons/ added to the metrics skip-list.

Expected steady state: ~1.5–2k active series (~15–20% of free tier) with growth vectors capped.

Test plan

  • New tests/server/test_metrics.py: label normalisation (templates kept, unmatched/garbage collapsed), histogram has no method label, no *_created in scrape output, static-mount skip-list.
  • Full gates: 1628 backend tests, ruff + pyright clean. ops/grafana/dashboards/frontend.json validated as JSON (6 panels remain).

🤖 Generated with Claude Code

… raw-path leak

Grafana Cloud free tier (10k series) was blown out at 14.5k+:

- user_page_views_total + its _created twin were 12.9k series (88%) —
  username(286) x path. Dropped entirely along with the three dashboard
  panels that read it.
- disable_created_metrics(): the OpenMetrics *_created companions doubled
  every counter/histogram and nothing read them (all "Unused" in the
  cardinality dashboard).
- http_request_duration_seconds: method label removed (no dashboard
  queried it) + buckets 10 -> 6; ~1,260 series -> ~450.
- Hardening: unmatched routes (bot POST probes) collapse to "(unmatched)"
  instead of minting a permanent series per raw URL; garbage verbs
  (PROPFIND, ...) collapse to OTHER; /class-icons/ joins the skip-list.

Expected steady state ~1.5-2k active series.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@VortexUK
VortexUK merged commit c25413b into main Jul 25, 2026
6 checks passed
@VortexUK
VortexUK deleted the fix/metrics-cardinality branch July 25, 2026 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant