- Date: 2026-07-13
- Environment: Google Cloud Run (
cortex, us-central1), live production service and revision config - Client: k6 via Docker, single client in Europe → us-central1 (network RTT ~145 ms floor is included in all latencies)
- Method: per-IP rate limiter (
RATE_LIMIT_DEFAULT, default 60/min) temporarily raised via env var for the run, then restored and re-verified (60 pass / overflow 429s confirmed after revert)
| Scenario | Load | Requests | Error rate | p50 | p95 | p99 | Max |
|---|---|---|---|---|---|---|---|
| API health (prod) | 20 req/s × 1m | 1,197 | 0.00% | 146 ms | 154 ms | 164 ms | 373 ms |
| API health (prod) | 200 req/s × 1m | 12,000 | 0.00% | 146 ms | 155 ms | 166 ms | 3.15 s |
- Production sustains 200 req/s with 0% errors and no latency degradation: p95 held flat (154 ms → 155 ms) from 20 to 200 req/s — a 10× load increase.
- 13,197 production requests, zero failures.
- Latency is network-bound, not server-bound: ~145 ms of every measurement is Europe→us-central1 RTT; server processing is single-digit ms (confirmed by the local runs below on identical code).
- Cloud Run autoscaling absorbed the 10× jump transparently; the single 3.15 s outlier is one instance cold start, after which p99 stayed ≤166 ms.
- Per-IP rate limiting (60/min) enforced in production, verified empirically: 70 parallel requests → exactly 60 accepted, remainder rejected with HTTP 429.
Not claimed: a long soak. A 10-minute 200 req/s sustained-stability run was intentionally not executed against live production from this session; run it during a maintenance window if you want a "sustained for N minutes" claim.
- Date: 2026-07-13
- Environment: local-dev (macOS, uvicorn single worker, Redis + Neo4j via Docker)
- Tool: k6 (
grafana/k6Docker image), constant-arrival-rate executor - Backend flags:
RATE_LIMIT_DEFAULT=100000/minute(raised for benchmark),RAG_PERF_HEADERS=true,RAG_SUGGESTIONS_DEFERRED=true
Local numbers are for bottleneck discovery and sizing, not public production-capacity claims (see
load-tests/README.md).
| Scenario | Load | Requests | Error rate | p50 | p95 | p99 | Max |
|---|---|---|---|---|---|---|---|
| API health | 20 req/s × 1m | 1,201 | 0.00% | 3.9 ms | 5.2 ms | 6.7 ms | 14.1 ms |
| API health | 200 req/s × 1m | 12,000 | 0.00% | 1.9 ms | 3.2 ms | 4.1 ms | 12.7 ms |
| Internal agent loop (real LLM) | 1 req/s × 30s | 29 | 0.00% | 1.21 s | 2.0 s | 2.6 s | 2.77 s |
- Sustains 200 req/s with 0% errors and p95 latency of 3.2 ms on the API layer (single uvicorn worker, local).
- Zero failed requests across 13,230 total requests in all scenarios.
- Real agent-loop turns (LLM call included, tools unbound) complete with median 1.2 s / p95 2.0 s at 1 req/s sustained.
- Built-in per-IP rate limiting (60/min default) verified under load: at 20 req/s the limiter correctly rejected 90% of over-quota requests with HTTP 429 before it was raised for the benchmark — a resilience feature, confirmed empirically.
- API latency dropped from 20 → 200 req/s (p95 5.2 → 3.2 ms): connection reuse across more concurrent VUs amortizes setup; the app layer is nowhere near saturation at 200 req/s.
- Agent-loop latency is dominated by the LLM provider call (~1.2 s median), not the framework — per k6 bottleneck hints and
x-rag-perfphase headers. - Peak k6 VUs: 50 preallocated, ≤3 used for the agent loop; 1 dropped iteration at 1 req/s (VU briefly busy on a 2.7 s turn).
- prod-health-20rps-report.md — production, 20 req/s
- prod-health-200rps-report.md — production, 10× load
- health-report.md — local, 20 req/s baseline
- health-200rps-report.md — local, 10× load
- internal-agent-loop-report.md — local, real
_run_agent_loopover HTTP
# backend
RATE_LIMIT_DEFAULT=100000/minute INTERNAL_DISPATCH_SECRET=bench-secret \
INNGEST_DEV=1 INNGEST_SIGNING_KEY=local-benchmark-signing-key \
uv run uvicorn src.api.endpoints:app --host 0.0.0.0 --port 8010
# health @ 200 rps
docker run --rm -v "$PWD:/work" -w /work \
-e BENCHMARK_BASE_URL=http://host.docker.internal:8010 \
-e BENCHMARK_RATE=200 -e BENCHMARK_PREALLOCATED_VUS=50 -e BENCHMARK_MAX_VUS=200 \
grafana/k6 run --summary-export reports/benchmarks/health-200rps-summary.json load-tests/health.js
# agent loop (real LLM calls)
docker run --rm -v "$PWD:/work" -w /work \
-e BENCHMARK_BASE_URL=http://host.docker.internal:8010 \
-e BENCHMARK_INTERNAL_SECRET=bench-secret -e BENCHMARK_BIND_TOOLS=false \
grafana/k6 run --summary-export reports/benchmarks/internal-agent-loop-summary.json load-tests/internal_agent_loop.js
# render markdown
uv run python scripts/render_k6_report.py --summary-json <summary.json> --scenario <name> \
--environment local-dev --target "<rate x duration>" --output <report.md>Re-run against the Cloud Run production deployment— done, see production section above.- Authenticated
agent_chat.jsrun (needsBENCHMARK_BEARER_TOKEN+BENCHMARK_AGENT_ID) to quantify the full RAG chat path under load. - 10-minute soak at 200 req/s against production (run during a maintenance window) to claim sustained stability, and a ramp test to find the actual saturation point.