All posts
Performance & Monitoring

p50, p95, and p99 Latency: Calculation and Examples

Calculate latency percentiles from a small dataset, reproduce the results in JavaScript, and understand what averages and tail latency reveal.

p50, p95, and p99 Latency: Calculation and Examples illustration
API Test Lab3 min read

A latency percentile gives the duration at or below which a proportion of measured requests completed. p50 describes the middle; p95 and p99 describe the slower tail. Report sample size, time window, failures, and calculation method.

Illustrative dataset

These 20 sorted durations are made-up teaching data in milliseconds, not a benchmark:

100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 500, 2000

Eighteen requests took 100 ms, one took 500 ms, and one took 2,000 ms. Their sum is 4,300 ms. The average is 4,300 / 20 = 215 ms. That average alone does not reveal the two-second request.

Calculate percentiles using nearest rank

Sort N values, calculate rank = ceil(p × N), and take the value at that one-based rank. Here p is 0.50, 0.95, or 0.99.

MetricCalculationResult
Mean4,300 / 20215 ms
p50ceil(0.50 × 20) = rank 10100 ms
p95ceil(0.95 × 20) = rank 19500 ms
p99ceil(0.99 × 20) = rank 202,000 ms

Ties mean more than 50% can be at or below p50. Do not assume exactly 5% are slower than p95. Nearest-rank p50 can also differ from a median definition that averages the two middle observations.

Reproduce it in JavaScript

Save as percentiles.mjs and run node percentiles.mjs.

const samples = [...Array(18).fill(100), 500, 2000];
function nearestRank(values, p) {
  if (!values.length || p <= 0 || p > 1) throw new Error('Invalid sample or p');
  const sorted = [...values].sort((a, b) => a - b);
  return sorted[Math.ceil(p * sorted.length) - 1];
}
console.log({
  mean: samples.reduce((sum, n) => sum + n, 0) / samples.length,
  p50: nearestRank(samples, 0.50),
  p95: nearestRank(samples, 0.95),
  p99: nearestRank(samples, 0.99),
});

Expected output: mean 215, p50 100, p95 500, p99 2000.

Why dashboards may disagree

Some tools interpolate between values; others estimate quantiles from histograms. With 20 observations, nearest-rank p99 is just the maximum. This arithmetic example is too small to characterize a stable production tail.

Check the tool's calculation method and whether its timer includes DNS, connections, transfer, and retries. This article does not assert that API Test Lab's backend uses nearest rank.

Use averages and percentiles together

Averages summarize total time; percentiles reveal variation. Compare them with throughput and failures for the same route, window, region, and workload. A high-volume fast route can hide a slow business-critical route in aggregate data.

Do not average daily p95 values to derive monthly p95. Merge compatible samples or histograms. Report timeouts separately rather than silently excluding them.

Apply this to a load test

Verify correctness, then run a controlled workload. Compare sample counts, percentiles, throughput, and errors before and after one change. Use the bottleneck workflow to connect tail latency to server measurements.

Inspect requests in API Test Lab, then check load allowances on pricing. A low p95 matters only when responses are correct and failures remain acceptable.

Share

Start testing your APIs

Try API Test Lab free. No credit card required.

Start free