Use labels when you need flexible, multi-dimensional metrics (for example, to filter or aggregate by endpoint and method). Labels keep metric names stable and make aggregation easier.
1) Single global counter (simple)
A basic approach increments the same counter for every endpoint. This gives you the global total but no breakdown by path.- Very simple to implement. Cons:
- No visibility into which endpoint handled the requests.
2) Separate counters per endpoint (scales poorly)
You can create a separate Counter for each path. This works but becomes brittle and hard to maintain as endpoints grow.- You lose a single metric name for aggregation unless you sum across many metric names.
- Adding endpoints requires creating and managing more metrics and updating dashboards/queries.
3) Recommended: a single Counter with labels
Use a single Counter and declare label names to create dimensions (for examplepath, and optionally method). Then increment the specific time series using labels(...):
http_requests_total, each differentiated by the path label. It keeps metric names stable and makes aggregation straightforward.
Example PromQL queries and exposition output
Using multiple labels (path + method)
Add other dimensions by declaring more label names and passing values tolabels() in the same order:
http_requests_total contains separate time series for each combination of path and method. Example queries:
- All series for the metric:
- Filter by HTTP method:
- Filter by path and aggregate methods for that path:
Be careful about high-cardinality label values (for example, user IDs, request IDs, or arbitrary URLs). Each unique label combination creates a new time series, which can consume a lot of memory and cause performance issues. Only use labels for dimensions you need to aggregate or filter on.
Quick comparison
Links and references
- Prometheus client_python documentation
- Prometheus query language (PromQL) basics
- Best practices for Prometheus metrics