> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# HistogramSummary

> How to instrument a Flask app with Prometheus histograms and summaries to measure and expose per-path per-method request latencies, customize buckets, and choose between histogram and summary

This guide shows how to instrument a Flask web application with Prometheus histogram and summary metrics to measure request latency per path and method. It walks through:

* Creating a histogram metric
* Recording per-request timings using Flask's `before_request` and `after_request` hooks
* Inspecting the generated Prometheus metrics (including default buckets)
* Customizing histogram buckets
* Using a summary metric and the Python-client limitation for quantiles

<Callout icon="lightbulb" color="#1CB2FE">
  Tip: Use per-path and per-method labels to slice latency metrics in Prometheus and visualize percentiles in Grafana or another dashboard.
</Callout>

## Basic histogram example

Create a histogram metric and observe latency for each request. Place the timing logic in Flask's `before_request` and `after_request` hooks so every request is measured automatically.

```python theme={null}
from prometheus_client import Histogram, start_http_server
from flask import Flask, request
import time

app = Flask(__name__)

LATENCY = Histogram(
    'request_latency_seconds',
    'Request Latency',
    labelnames=['path', 'method']
)

def before_request():
    request.start_time = time.time()

def after_request(response):
    request_latency = time.time() - request.start_time
    LATENCY.labels(
        request.path,
        request.method
    ).observe(request_latency)
    return response

if __name__ == '__main__':
    start_http_server(8000)
    app.before_request(before_request)
    app.after_request(after_request)
    app.run()
```

How it works:

* `before_request()` records the timestamp when the request arrives (`time.time()`).
* `after_request()` computes the latency by subtracting the start time from the current time, then calls `observe()` on the histogram with the appropriate labels.
* `start_http_server(8000)` exposes metrics on port 8000 for Prometheus to scrape.

<Callout icon="lightbulb" color="#1CB2FE">
  Note: You can store the `start_time` on the `request` object because Flask exposes a request-local proxy for each incoming request.
</Callout>

## Example metric output

When you scrape or query the histogram metric in Prometheus, the client creates buckets and count metrics. A scraped output may look like:

```plaintext theme={null}
# HELP request_latency_seconds Request Latency
# TYPE request_latency_seconds histogram
request_latency_seconds_bucket{le="0.005",method="GET",path="/cars"} 0.0
request_latency_seconds_bucket{le="0.01",method="GET",path="/cars"} 0.0
request_latency_seconds_bucket{le="0.025",method="GET",path="/cars"} 0.0
request_latency_seconds_bucket{le="0.05",method="GET",path="/cars"} 1.0
request_latency_seconds_bucket{le="0.075",method="GET",path="/cars"} 3.0
request_latency_seconds_bucket{le="0.1",method="GET",path="/cars"} 3.0
request_latency_seconds_bucket{le="0.25",method="GET",path="/cars"} 4.0
request_latency_seconds_bucket{le="0.5",method="GET",path="/cars"} 6.0
request_latency_seconds_bucket{le="0.75",method="GET",path="/cars"} 6.0
request_latency_seconds_bucket{le="1.0",method="GET",path="/cars"} 8.0
request_latency_seconds_bucket{le="2.5",method="GET",path="/cars"} 8.0
request_latency_seconds_bucket{le="5.0",method="GET",path="/cars"} 8.0
request_latency_seconds_bucket{le="7.5",method="GET",path="/cars"} 8.0
request_latency_seconds_bucket{le="10.0",method="GET",path="/cars"} 8.0
request_latency_seconds_bucket{le="+Inf",method="GET",path="/cars"} 8.0
request_latency_seconds_count{method="GET",path="/cars"} 8.0
request_latency_seconds_sum{method="GET",path="/cars"} 1.234
```

The client provides helpful default buckets suitable for many web applications, but you will often want to customize them.

## Customizing histogram buckets

To change bucket boundaries, pass the `buckets` parameter when you instantiate the `Histogram`. For low-latency, high-resolution needs, provide a list of bucket upper bounds:

```python theme={null}
LATENCY = Histogram(
    'request_latency_seconds',
    'Flask Request Latency',
    labelnames=['path', 'method'],
    buckets=[0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1]
)
```

Adjust buckets to match the latency distribution of your application. Use finer buckets for low latency applications and wider buckets for higher-latency systems.

## Using a Summary metric

A `Summary` records observed values and can calculate configurable quantiles (in some client libraries). The usage pattern is almost identical to a `Histogram`: create the metric and call `.observe()` with the measured latency.

```python theme={null}
from prometheus_client import Summary

LATENCY_SUMMARY = Summary(
    'request_latency_seconds',
    'Flask Request Latency',
    labelnames=['path', 'method']
)

# Later, in your after_request:
LATENCY_SUMMARY.labels(request.path, request.method).observe(request_latency)
```

<Callout icon="warning" color="#FF6B6B">
  Warning: The Python Prometheus client does not implement configurable quantiles for Summary metrics the same way some other language clients do. If you need server-side quantiles, prefer Histograms and compute quantiles in Prometheus (e.g., `histogram_quantile()`), or check the client library updates for support in your language.
</Callout>

## Histogram vs Summary — quick comparison

| Metric Type | Use Case                                                                                              | Notes                                                                                                               |
| ----------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Histogram   | Ideal for calculating quantiles in Prometheus (via `histogram_quantile`) and exposing bucketed counts | You must choose buckets; Prometheus can compute quantiles from buckets                                              |
| Summary     | Records quantiles and sum/count on the client side                                                    | Some client libraries (like Python) lack configurable quantiles; server-side quantile calculation may be preferable |

## Links and references

* [Prometheus Python client](https://github.com/prometheus/client_python)
* [PromQL histogram\_quantile()](https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile)
* [Flask request lifecycle (before\_request/after\_request)](https://flask.palletsprojects.com/en/latest/api/#flask.Flask.before_request)

Use the examples above to add latency instrumentation to your Flask app, tune bucket boundaries to your observed latency distribution, and choose between Histogram and Summary depending on your quantile needs and client library support.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/prometheus-certified-associate-pca/module/0c0155c7-00c8-4ca2-a061-e66baa1a3216/lesson/3b52f98d-3825-4cfd-8293-5902005dd533" />
</CardGroup>
