· 2 min read
p95 in an uptime monitor: the nearest-rank method and what it does not hide
How uptime-monitor computes p50/p95 latency and uptime, why the nearest-rank method was chosen, and where those numbers can mislead.
The monitor shows p50 and p95 latency of successful checks over 24 hours. The mean is a poor fit here: one outlier shifts it, while the slow tail is exactly what users feel.
Nearest rank
The p-th percentile is the element of the sorted list at rank ceil(p/100 * N). For 20 measurements, p95 is the 19th in ascending order. There is no interpolation: the result is always a real measurement.
rank := int(math.Ceil(p / 100 * float64(len(s))))
return s[rank-1]
The function is pure: the slice is not modified, an empty slice returns 0, and the p<=0 and p>=100 bounds are handled separately. That makes it easy to cover with tests.
Uptime
Uptime is the share of successful checks, ok / total * 100. An important caveat from the README: it is computed from the number of checks, not from durations, so figures for checks with different intervals are not equally precise.
Where the numbers can mislead
- With few measurements, p95 is almost the maximum.
- Aggregates run as queries over the raw history: instant for dozens of checks, thousands would need pre-aggregation.
- Checks run from a single machine; this is not distributed monitoring from several regions.