Use a Gauge to represent values that can both increase and decrease (for example, current in-flight requests). For strictly monotonic totals (only increasing), prefer a Counter.
Why use a Gauge for in-progress requests
- Gauges support incrementing, decrementing, and setting an explicit value.
- They are ideal for metrics that fluctuate over time (CPU load, queue lengths, active requests).
- When tracking active requests, a Gauge gives you a real-time view of concurrent work.
Example: instrumenting Flask with a Gauge
Note the order of label names in the Gauge declaration must match the order of values passed tolabels().
Flask’s
after_request handlers are not executed if an exception is raised while handling the request. To guarantee the gauge is decremented for error cases, decrement in a @app.teardown_request handler or use try/finally inside your request handling.Ensuring decrement on exceptions
A safe pattern is to decrement usingteardown_request, which runs regardless of exceptions:
Avoid very high-cardinality label values (e.g., raw request paths with IDs, user IDs). Prefer normalized route templates like
/cars/{id}, status codes, or handler names to prevent metric explosion and high memory usage in Prometheus.Quick reference: Gauge operations
Behavior summary:
- Increment the gauge when a request starts:
inc(). - Decrement it when the request finishes:
dec(). - Optionally set an explicit value with
set(value).
How the metric appears (Prometheus exposition format)
Example exposition output that Prometheus would scrape:Best practices and considerations
- Label ordering: declare label names in the same order you pass values to
labels(). - Cardinality: keep the number of unique label combinations low. Normalize dynamic values (IDs, timestamps) before adding them as labels.
- Error handling: always ensure decrements run even on exceptions (use teardown handlers or
try/finally). - Monitoring: pair gauges with counters or histograms (e.g., request duration) for a fuller picture of system health.