Notebook · Executable ideas

Every millisecond has a story

A Python notebook showing how a small slow cohort changes tail latency while the average stays low.

Download Python notebook
In this article
  1. The average is not the experience
  2. Budget for the slow path
  3. Choose the measurement window
  4. The source, in full

The average is not the experience #

Consider a synthetic workload: 95 requests take 40 ms each, and 5 take 800 ms. The mean weights every request equally; a percentile identifies a position in the sorted distribution.

Mean: 78 ms. P99: 800 ms. The mean hides a slow path that one in twenty requests takes.

Budget for the slow path #

A service that calls several dependencies can inherit the tail of each one. Deadlines, bounded retries, and queue limits should form one coherent budget.

Choose the measurement window #

This calculation uses the nearest-rank percentile: sort the observations and select rank ceil(p × n). With 100 requests, p99 is the 99th observation. Track percentiles alongside request volume and the measurement window; changing either can change how much evidence supports the reported tail.

The source, in full #

latency-budget.py
# Metadata lives in ../latency-budget.json. This notebook uses synthetic data.
import marimo
 
__generated_with = "0.16.5"
app = marimo.App(width="medium")
 
@app.cell
def _():
    import marimo as mo
    return (mo,)
 
@app.cell
def _(mo):
    mo.md("""
    ## The average is not the experience
    Consider a synthetic workload: 95 requests take 40 ms each, and 5 take 800 ms.
    The mean weights every request equally; a percentile identifies a position
    in the sorted distribution.
    """)
    return
 
@app.cell
def _():
    import math
    latencies = [40] * 95 + [800] * 5
    def percentile(values, p):
        ordered = sorted(values)
        return ordered[max(0, math.ceil(p * len(ordered)) - 1)]
    mean = sum(latencies) / len(latencies)
    p99 = percentile(latencies, 0.99)
    return latencies, mean, p99
 
@app.cell
def _(mo, mean, p99):
    mo.md(f"Mean: **{mean:.0f} ms**. P99: **{p99:.0f} ms**. The mean hides a slow path that one in twenty requests takes.")
    return
 
@app.cell
def _(mo):
    mo.md("""
    ## Budget for the slow path
    A service that calls several dependencies can inherit the tail of each one.
    Deadlines, bounded retries, and queue limits should form one coherent budget.
 
    ## Choose the measurement window
    This calculation uses the nearest-rank percentile: sort the observations and
    select rank ceil(p × n). With 100 requests, p99 is the 99th observation.
    Track percentiles alongside request volume and the measurement window;
    changing either can change how much evidence supports the reported tail.
    """)
    return
 
if __name__ == "__main__":
    app.run()
 

Notebook output

Related articles