Explains using Prometheus labels to track per-path and per-method HTTP request metrics, advantages over per-path metrics, aggregation examples, and warnings about label cardinality.
As your application grows to expose multiple endpoints—for example, endpoints for cars (/cars) and boats (/boats)—you may want both a global request count and per-path counts. Incrementing a single global counter for every endpoint tracks total traffic, but it doesn’t tell you how that traffic is distributed across paths.Example endpoints:
If you want per-path totals, one naive solution is creating a distinct Counter for each path and incrementing the appropriate one:
from prometheus_client import CounterCAR_REQUESTS = Counter( "requests_cars_total", "Total number of requests for /cars path")BOATS_REQUESTS = Counter( "requests_boats_total", "Total number of requests for /boats path")@app.get("/cars")def get_cars(): CAR_REQUESTS.inc() return ["toyota", "honda", "mazda", "lexus"]@app.post("/cars")def create_cars(): CAR_REQUESTS.inc() return "Create Car"@app.get("/boats")def get_boats(): BOATS_REQUESTS.inc() return ["boat1", "boat2", "boat3"]@app.post("/boats")def create_boat(): BOATS_REQUESTS.inc() return "Create Boat"
This approach works, but it scales poorly. You end up with one metric name per path, making application-wide aggregations awkward: queries must reference every metric name and you must remember to update instrumentation whenever you add or remove endpoints. This increases maintenance overhead and makes queries error-prone.A better practice is to use labels (also called dimensions). Define a single metric and add a path label at metric creation time. Then, when incrementing, provide the label value.
With this pattern, each distinct path value produces a separate time series under the same metric name http_requests_total. That makes filtering and aggregation simple and reliable.
Prometheus will expose each labeled time series. For example:
Use labels to keep metrics organized and queryable, but be mindful of cardinality: labels that can take many unique values (like user IDs, session tokens, or request IDs) cause a large number of time series and can harm performance and storage.
Approach
Pros
Cons
When to use
One metric per path (multiple metric names)
Simple to implement
Hard to aggregate, high maintenance, error-prone when adding endpoints
Very small projects with few endpoints and no need for aggregation
Most web services; use for per-path, per-method, per-status counts
Use labels to keep metrics organized and queryable. However, be cautious about label cardinality: labels with high cardinality (for example, user IDs, session IDs, or other highly unique values) can produce a huge number of time series and cause performance and storage problems. Restrict labels to a small, well-defined set of values.