When you’re processing load test timings (or any latency distribution), you typically want buckets like p50/p95/p99 quickly. percently provides a small, fast Rust implementation exposed to Python.
- Fast: Rust core
- Simple API: one call to compute a percentile
- Python-friendly: works with regular lists/iterables of floats
Using uv:
uv add percentlyUsing pip:
pip install percentlyimport percently
data = [10.5, 22.0, 18.7, 19.2, 30.1, 25.3]
# Calculate the 95th percentile (f64)
p95 = percently.percentile(data, 95)
print(f"95th percentile: {p95:.2f}")If you have a generator/iterable and want running percentile estimates without loading all values into memory, use stream.
import percently
def timings():
for i in range(1, 1_000_001):
yield float(i % 10_000) / 10_000.0
# Yield an updated p95 estimate every 1000 samples (approximate, bounded memory)
for est in percently.stream(timings(), 95, every=1000):
last = est
print("final approx p95:", last)Notes:
stream(..., 0, ...)yields the running min (exact)stream(..., 100, ...)yields the running max (exact)- All values must be finite floats (no NaN/inf)
Build/install locally (editable) with maturin:
uv sync
uv run maturin developThis repo is configured for signed release commits/tags and tag-based publishing:
- Create a signed tag (e.g.
0.1.4) - GitHub Actions (tag-triggered) builds wheels/sdist and publishes to PyPI
Recommended (cargo-style) tool: cargo-release
cargo install cargo-release
# Patch release: bumps Cargo.toml version, commits (signed), creates signed tag, pushes
cargo release patch --executeMIT — see LICENSE.