Skip to content

fix(prometheus)!: default group_path to True to bound metric cardinality#4925

Merged
provinzkraut merged 3 commits into
litestar-org:mainfrom
Bishwas-py:fix/prometheus-group-path-default
Jul 16, 2026
Merged

fix(prometheus)!: default group_path to True to bound metric cardinality#4925
provinzkraut merged 3 commits into
litestar-org:mainfrom
Bishwas-py:fix/prometheus-group-path-default

Conversation

@Bishwas-py

@Bishwas-py Bishwas-py commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #4891.

PrometheusMiddleware records the path metric label from the raw request
path by default. On a route with path parameters, every distinct value seen
in traffic becomes a new time series, so the metric set grows without bound
as traffic hits distinct parameter values, for example /users/1,
/users/2, /users/3, ... each get their own series.

group_path=True already avoids this by using the route template
(/users/{user_id}) instead of the raw path. The mechanics of that option
were made robust in #3533, #3687 and #3784. The remaining gap was that the
safe behavior was opt-in, so users hit the cardinality trap silently by
using the default.

Fix

Flip the default to True. Raw-path behavior stays fully available via
group_path=False for anyone who wants it. Also updated the docs example's
local default to match, so the snippet shown in the Prometheus docs page
reflects the new default rather than silently diverging from it.

How was this tested

Added two tests in tests/unit/test_plugins/test_prometheus.py:

  • PrometheusConfig().group_path is True
  • a route with a path parameter hit with three different values produces a
    single path="/users/{user_id}" series, not three separate raw-path
    series

Both fail on main (raw paths leak through) and pass with this change.

Also ran the reproduction script from the issue directly:

group_path=False: 5 distinct app path series -> ['/users/1', '/users/2', '/users/3', '/users/4', '/users/5']
group_path=True:  1 distinct app path series -> ['/users/{user_id}']

With this change, calling PrometheusConfig() with no arguments now
produces the group_path=True result above instead of the False one.

Full suite: tests/unit/test_plugins/ and tests/examples/test_contrib/prometheus/ pass (491 tests), no existing test asserted raw-path grouping since none of them use parameterized routes.


📚 Documentation preview 📚: https://litestar-org.github.io/litestar-docs-preview/4925

PrometheusMiddleware recorded the raw request path as the path metric
label. On a route with path parameters, every distinct value seen in
traffic became a new time series, so the metric set grew without bound.

group_path=True already avoided this by using the route template
instead of the raw path, but it was opt-in, so users hit the
cardinality trap silently by default.

Flip the default. Raw-path behavior stays available via
group_path=False for anyone who wants it.

Fixes litestar-org#4891
@Bishwas-py Bishwas-py requested review from a team as code owners July 14, 2026 15:30
@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.30%. Comparing base (2453f45) to head (cf7c82a).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4925   +/-   ##
=======================================
  Coverage   67.30%   67.30%           
=======================================
  Files         293      293           
  Lines       15230    15230           
  Branches     1728     1728           
=======================================
  Hits        10251    10251           
  Misses       4832     4832           
  Partials      147      147           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@provinzkraut provinzkraut changed the title fix(prometheus): default group_path to True to bound metric cardinality fix(prometheus)!: default group_path to True to bound metric cardinality Jul 16, 2026
@provinzkraut provinzkraut merged commit 143fae3 into litestar-org:main Jul 16, 2026
23 checks passed
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.

Enhancement: Prometheus group_path=False default causes unbounded metric cardinality (memory growth)

2 participants