diff --git a/README.md b/README.md index 07bc768..8462521 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@

- Latency: median 112 μs, p99 < 1 ms · No external state (no Redis / DB) + Latency: < 70 µs enforcement overhead · 195k RPS max throughput · No external state (no Redis / DB)

--- @@ -272,16 +272,14 @@ Policies are versioned JSON — commit them to Git, review changes in PRs, roll ## Performance -### Benchmark methodology (March 4, 2026) +### Benchmark methodology (March 2026) -- **Host:** AWS `c7i.2xlarge` (8 vCPU, 16 GiB RAM) -- **OS:** Ubuntu 24.04.3 LTS +- **Hosts:** 2 × AWS `c7i.xlarge` (4 vCPU, 8 GiB each), cluster placement group, eu-central-1 +- **OS:** Ubuntu 24.04 LTS - **Runtime:** OpenResty 1.29.2.1, Fairvisor latest `main` (no Docker) - **Load tool:** `k6` v0.54.0, `constant-arrival-rate`, 10,000 RPS for 60s, 10s warmup - **Benchmark script:** `run-all.sh` from `fairvisor/benchmark` -- **CPU isolation (single-host run):** `taskset` split - - OpenResty/backend on cores `0-3` - - k6 on cores `4-7` +- **Topology:** two-host — Fairvisor and k6 on separate machines (VPC private network) - **Decision endpoint contract:** `POST /v1/decision` with `X-Original-Method` and `X-Original-URI` - **Note:** reverse proxy numbers include policy evaluation and upstream proxy hop to backend nginx. @@ -289,22 +287,23 @@ Policies are versioned JSON — commit them to Git, review changes in PRs, roll | Percentile | Decision service | Reverse proxy | Raw nginx (baseline) | |---|---|---|---| -| p50 | 112 μs | 241 μs | 71 μs | -| p90 | 191 μs | 376 μs | 190 μs | -| p99 | 426 μs | 822 μs | 446 μs | -| p99.9 | 2.99 ms | 2.98 ms | 1.61 ms | +| p50 | 304 μs | 302 μs | 235 μs | +| p90 | 543 μs | 593 μs | 409 μs | +| p99 | 2.00 ms | 1.79 ms | 1.95 ms | +| p99.9 | 4.00 ms | 5.12 ms | 3.62 ms | + +**Enforcement overhead over raw nginx baseline: p50 +69 µs / p90 +134 µs.** ### Latest max sustained throughput (single instance) | Configuration | Max RPS | |---|---| -| Simple rate limit (1 rule) | 110,500 | -| Complex policy (5 rules, JWT parsing, loop detection) | 67,600 | -| With token estimation | 49,400 | +| Simple rate limit (1 rule) | 195,000 | +| Complex policy (5 rules, JWT parsing, loop detection) | 195,000 | **No external datastore.** All enforcement state lives in in-process shared memory (`ngx.shared.dict`). No Redis, no Postgres, no network round-trips in the decision path. -> Reproduce: `git clone https://github.com/fairvisor/benchmark && cd benchmark && ./run-all.sh` +> Reproduce: `git clone https://github.com/fairvisor/benchmark && cd benchmark && bash run-all.sh` ## Deployment