Skip to main content
Let’s extend our application so it exposes separate endpoints for cars and boats. We still want a single metric that tracks total HTTP requests, but we also want to break it down by endpoint (path) and optionally by HTTP method. Below are recommended patterns to track requests with the Python Prometheus client, including examples, PromQL queries, and guidance on label usage.
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.
Pros:
  • 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.
Drawbacks:
  • 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.
Use a single Counter and declare label names to create dimensions (for example path, and optionally method). Then increment the specific time series using labels(...):
This yields multiple time series under the metric name 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 to labels() in the same order:
Now 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

Watch Video