A latency observation needs a boundary and a unit. These fixtures contain nonnegative milliseconds for completed requests; no code sleeps, runs a benchmark or contacts a service. The sample may omit requests, and completion-only logging can exclude timed-out work. The summary therefore describes observed values. It does not establish the latency distribution of all customer requests.
The arithmetic mean is useful for overall cost, but it can conceal the tail. Four observations of 1,1,1,197 ms have mean 50 ms. Most are fast, and one is much slower. A target-success fraction answers how many observations meet a chosen latency boundary. A percentile answers which ordered observation represents a chosen rank under a named convention. Show support alongside both.
import math
sample = sorted([197, 1, 1, 1])
q = .95
print(sample[math.ceil(q * len(sample)) - 1])
print(sum(x <= 100 for x in sample) / len(sample))This course uses nearest-rank: for n>0, rank is ceil(q*n), starting at one, so the Python index is rank minus one. It accepts 0<q<=1. Under this convention p50 of [1,2,3,4] is 2; an interpolating convention could yield 2.5 instead. Neither label alone explains the algorithm. For a twenty-observation sample with nineteen 1 ms requests and one 1000 ms request, nearest-rank p95 is still 1 ms. Inspect the sample and its support before treating a tail label as a complete safety guarantee.
A histogram preserves counts at defined boundaries. In this lab the finite buckets are cumulative: the bucket at 10 ms counts every observation <=10. An observation exactly on a boundary belongs to that bucket. The final implicit +infinity bucket equals the total sample count. Do not add cumulative buckets together, because the same observation contributes repeatedly.
Compatible bucket counts can be added across instances before computing an approximate fleet percentile. Individual instance p95 values cannot generally be averaged to recover fleet p95; they discard support and distribution information. The build retains raw observations, so it selects an exact sample rank. It does not reproduce a monitoring backend's histogram interpolation, native histogram implementation or quantile error guarantees.
Empty observations produce count zero and None for mean, percentile and target fraction. Reporting 0 ms would invent a fast request. Reject nonfinite and negative values before sorting; validate quantile and bucket boundaries even when there are no observations. Copy input so a summary does not silently reorder the caller's data.
The checks make rank conventions and inclusive boundaries explicit. Bug hunts expose a dropped bucket tie and a rank/index conversion error. The build handles generators, repeated values, empty bounds and invalid numeric types using only the standard library. Production instrumentation requires a separate decision about timeouts, sampling, measurement boundaries and compatible aggregation.