Aggregate Latency Histogram Buckets to a Quantile
Problem Statement
Prometheus-style latency histograms store cumulative counts per bucket boundary. Estimate a quantile by linear interpolation within the bucket where the quantile rank falls.
Background
Buckets are given as ascending (upper_bound, cumulative_count) pairs (cumulative = number of samples <= upper_bound). The last bucket's count is the total. For quantile q, the target rank is q * total. Find the first bucket whose cumulative count >= rank; linearly interpolate between the previous bucket's upper bound (or 0) and this bucket's upper bound based on where rank falls within [prev_count, this_count].
Your Task
def histogram_quantile(buckets, q):
Return the estimated quantile value (float), rounded to 4 decimals.
Input Format
- buckets (list of (upper_bound, cumulative_count), ascending), q (float in [0,1]).
Output Format
- A float rounded to 4 decimals.
Sample
print(histogram_quantile([(1.0, 10), (2.0, 20), (5.0, 30)], 0.5))
Output:
1.5
Example
print(histogram_quantile([(1.0, 10), (2.0, 20), (5.0, 30)], 0.5))
1.5
- Determine the total number of samples from the last bucket's cumulative count: .
- Calculate the target rank for the 50th percentile (): .
- Identify the bucket containing the rank by finding the first cumulative count : the first bucket has count (too low), and the second has count (sufficient), so the relevant interval is between bounds and .
- Compute the linear interpolation fraction within this bucket, using the previous cumulative count () and the current span (): .
- Apply the fraction to the bucket width to estimate the value: .
- The final output is 1.5
Constraints
- rank = q * total (total = last cumulative count).
- Interpolate in the bucket where cumulative first reaches rank, between prev bound (or 0) and this bound over
[prev_count, this_count]. - Round to 4 decimals; buckets non-empty and ascending.