Skip to main content
Request overhead p50 12.38ms · completion route measured on one worker

Performance
Benchmarks

We publish what is measured and what is not. Measured: single-user latency on the production node, and the cost of the full security chain on the completion route on one worker of a development workstation. No production-node load figure exists yet. Here is what G8KEPR adds to a request, and the scripts to measure it on your own hardware.

12.38ms
Request p50, production node
20.05ms
Request p99, production node
0.857
Held-out precision
3.12%
Held-out FPR

Context matters. The only under-load figures on this page are the completion-route run below: one worker on a shared development workstation, against an instant stub model. They are not production capacity. The older committed load runs recorded mostly rate-limit rejections, so their requests-per-second counts rejections, not capacity (loadtests/RUNBOOK_throughput.md). The k6 and Locust scripts are in the repo (tests/load, loadtests) — run them on your own hardware.

Measured single-user latency, the held-out detection test, and one-worker throughput of the completion route on a development workstation (details below).

12.38 ms
p50 request
production node, through auth
15.47 ms
p95 request
production node, through auth
20.05 ms
p99 request
production node, through auth
0.788
Recall
496 held-out attacks
0.857
Precision
held-out, N=2,580
3.12%
False-positive rate
2,084 held-out benign prompts
11
Redis caches
TTL + fail-safe
4.975/s
Completions, one worker
dev workstation, stub model, full chain
Defined, not yet enforced

Load-Test Thresholds

These thresholds are defined in tests/load/k6-ci.js. No CI job runs them today (the load-test workflows are disabled), and the last committed run failed all 14 of its thresholds. They are the bar a run has to clear, not a result.

Smoke (1 VU · 30s)

Sanity check — single-user baseline, tightest thresholds

p95
< 100ms
p99
< 200ms
Throughput
> 50 req/s
Error rate
< 0.5%
Load (50 VU · 3 min)

Sustained-load threshold

p95
< 200ms
p99
< 500ms
Throughput
> 100 req/s
Error rate
< 1%
Stress (200 VU · 1 min)

Burst threshold

p95
< 500ms
p99
< 1,000ms
Throughput
> 150 req/s
Error rate
< 5%

Per-Endpoint Performance Targets

Published targets from tests/load/benchmark_results.json

Endpoint
Category
p50 target
p95 target
GET /health

Readiness probe

Infrastructure
50ms
100ms
POST /api/keys/validate

API key authentication

Auth
50ms
200ms
GET /api/gateway/proxy

Gateway passthrough

Gateway
80ms
200ms
GET /api/compliance/frameworks

Compliance data fetch

Compliance
150ms
500ms
GET /api/audit-logs

Audit log retrieval

Audit
200ms
500ms
POST /api/threat-intelligence/analyze

Full AI threat scan

AI Analysis
300ms
1000ms

These are targets, not measurements. On the completion route detection runs in line, before the reply is returned; its measured cost is in the security-tax section below.

Cascading Detection · Cheap Tiers First

Threat Detection Latency by Tier

The detection engine is a four-tier cascade. Cheap tiers run first; expensive tiers escalate only when confidence is low. The fast path stays under 25ms on every request.

T1
Regex Pattern Matching< 1 ms

~340 pre-compiled regex rules evaluated on every request: prompt injection, jailbreak, role hijacking, PII extraction and context manipulation. High-confidence (>0.9) hits block immediately.

T2
Embedding Similarity5-15 ms

SentenceTransformer cosine similarity vs. known injection vectors. Catches semantic equivalents that bypass literal regex. Lazy-loaded model.

T3
NLI Zero-Shot Classification< 15 ms

Intent classification gate. Plus base64 / URL / hex decode-then-rescan, NFKD normalization, character-split detection, Shannon entropy.

T4
LLM Escalation (rare)200-2,000 ms

High-uncertainty inputs only. Routed via the AI Gateway to an LLM provider. Async — fail-open on timeout to avoid blocking response.

Fast path p99

< 25ms regex-only · < 40ms with ML scoring

Detection accuracy

Scored on a frozen 2,580-sample held-out set it was never trained on: 0.788 recall, 0.857 precision and a 3.12% false-positive rate. The test fails the build on any regression. On a separate set of 50 adversarial-evasion + 50 benign prompts, 45 of 50 evasions (90%) are caught.

What G8KEPR Does With Those Milliseconds

The Request Pipeline

Every request goes through only the steps it needs. On the completion route the detectors, guardrails and response checks run in line, before the reply is returned; their measured total is in the security-tax section below.

1
JWT + API key validation1–3ms

In-memory JWT signature check + Redis GET for key scope

2
Rate limit check2–5ms

Redis INCR with sliding window — single round-trip

3
Circuit breaker evaluation< 1ms

In-memory state check — no I/O

4
Threat detection (cached)5–10ms

Redis semantic cache hit — no model call needed

4b
Threat detection (uncached)50–200ms

Pattern matching + optional ML scoring. Runs in line on the completion route: a refused prompt never reaches the model.

5
Audit log write2–8ms

Async PostgreSQL insert — does not add to request latency

Pass-through total: ~15–30ms added overhead for JWT validation + rate limit + circuit breaker. No more.

Threat analysis: runs in line on the completion route, before the reply is returned, so a refused prompt never reaches the model. The time it costs is measured in the security-tax section below.

Built for Throughput

Architecture Choices That Keep Overhead Low

Performance is a first-class design constraint, not an afterthought. These are the specific choices that give G8KEPR its overhead profile.

Async FastAPI

All endpoints are async/await — no thread blocking on I/O. Single worker can handle hundreds of concurrent connections without spawning threads.

Python asynciouvicornNo GIL blocking

Redis Singleflight Cache

Identical concurrent requests to Redis are coalesced — only one cache miss fires even under burst. Semantic cache prevents re-running ML models for repeated prompt patterns.

SingleflightSemantic dedup<10ms cache hit

Connection Pooling

PostgreSQL connections are pooled via asyncpg — no per-request connect overhead. Pool sizing is tuned per deployment based on DB capacity.

asyncpg poolNo reconnect overheadConfigurable size

Brotli + HTTP/3

API responses are Brotli-compressed at the edge, reducing wire bytes by ~30% vs gzip. HTTP/3 eliminates head-of-line blocking for clients that support it.

Brotli compressionHTTP/3 QUIC~30% smaller payloads
How G8KEPR Behaves Under Load

Performance Choices Built into the Architecture

These aren't tunables that need configuring after deployment — they're structural decisions that keep latency flat as load scales. None of them are present in a generic API gateway plus third-party AI guardrail stack.

4-Tier Cascading Detection

Cheap tiers run first. 99% of traffic terminates at Tier 1 regex (<1ms). Only ambiguous inputs escalate to embeddings (5-15ms), NLI (<15ms), or LLM (rare). p99 stays <25ms regex-only, <40ms with ML.

fast-path < 25msmodules/threat_detection/

Auto Anthropic Prompt Caching

SHA-256 fingerprint per system prompt. After 2 identical prompts, auto-injects cache_control:ephemeral. Break-even at 2 calls (38% off). 88% off at 10 calls. Zero SDK changes.

88% savings · 10 callsgateway/cache_optimizer.py

Adaptive Z-Score Breaker

Statistical baseline per provider per hour-of-day, not static thresholds. 4 rolling windows (1m / 5m / 15m / 1hr). Progressive recovery 10/25/50/100%. Off by default; enable with ADAPTIVE_CB_ENABLED.

3σ · 4 windowsgateway/router.py

Redis Singleflight Cache

Identical concurrent requests are coalesced — only one cache miss fires under burst. Semantic cache prevents re-running ML for repeated patterns. Cache miss is always safe; every cache has a documented fallback path.

burst-safe11 Redis caches · TTL fail-safe
Production node · 2026-09-12

Actual Numbers, Not Targets

Per-request overhead measured on the production node: one client sending 150 sequential requests to 127.0.0.1 through the full middleware stack and authentication (an unrouted path, so no handler runs), after 15 warm-up requests. No CI job re-runs it.

Per-request overhead · production node
p50
12.38 ms
p95
15.47 ms
p99
20.05 ms

This is the HTTP path up to authentication, not detection time. Reproduce on the host with python3 scripts/perf/measure_request_latency.py -n 150 --warmup 15.

Security tax · POST /api/v1/gateway/completions · 2026-10-15
Overhead p50
185.34 ms
Overhead p95
267.40 ms
Throughput, one worker
4.975 completions/s

Overhead is the latency of a completion through G8KEPR minus the same request sent straight to the same stub model: 360 requests each at 2 per second, every security control at its shipped default, no rate limit raised. It covers everything the gateway adds (authentication, rate limits, the request-side detectors and guardrails, routing, the verification engine and the response filter), and the stub answers in about a millisecond, so a real model's own latency comes on top. Throughput is 8 clients sending back to back for 120 seconds. Measured on one uvicorn worker of a shared development workstation (AMD Ryzen 5 3600XT), not production hardware; a repeat run gave 189.36 / 283.98 ms and 4.825 completions/s. Artifact and method: docs/benchmarks/gateway-security-tax/.

Production-node load: not measured. The committed 50-user Locust run recorded 5,233 failures in 6,147 requests, almost all of them rate-limit rejections, so its requests-per-second counts rejections rather than capacity. The method is in loadtests/RUNBOOK_throughput.md.

Why G8KEPR Adds Less Overhead Than You Expect

Self-hosting removes the network hop to a remote gateway. What is left is processing, and that is measured above.

Factor
Cloud-Only Gateway
G8KEPR Self-Hosted
Network latency to gateway
Add 20–80ms RTT — gateway is in another datacenter
Near-zero — deploy alongside your services
Authentication overhead
Remote auth call on every request — adds 50–200ms
In-process JWT check + Redis local lookup — 1–10ms
Rate limit check
Centralized rate-limit service — extra network hop
Local Redis — 2–5ms single round-trip
Cold start / scale-out
Vendor cold starts add unpredictable spikes
Persistent uvicorn workers — no cold starts
Vendor lock-in on hardware
Cannot scale beyond vendor-provided instance types
Scale to your hardware — upgrade without migration
11 Caches · TTL-Based · Always Fail-Safe

How The Latency Is Achieved

Eleven distinct Redis caches with explicit TTLs and explicit fallbacks. Cache miss is always safe — Redis provides performance, not correctness. Every cache has a documented degraded path.

Cache
TTL
Threat detection results
300s
MCP tool permissions
300s
Agent rate limits
300s
AI Gateway provider health
30s
LLM prompt response cache
1 hour
Routing decisions
5 min
Token blacklist
Until expiry
OAuth state
15 min
2FA attempts
Per window
Org analytics summary
1 hour
Policy validation
60s
ETag two-tier caching

Public paths: max-age=60, stale-while-revalidate=300 · Private paths: max-age=30, must-revalidate · 304 Not Modified on hit

Pooled Redis client

Singleton with max 50 connections · 5s connect timeout · TLS for remote hosts · background ping every 30s · Redis ops < 1ms typical

Open Methodology

Run It Yourself

All test scripts are in the repository. No black-box benchmarks — every number on this page is reproducible. Run against the demo API or your own self-hosted deployment.

tests/load/k6-ci.js

CI gate — smoke + 50 VU load + 200 VU stress

tests/load/k6-baseline.js

Authoritative baseline — 5 key endpoints at 50 VU

tests/load/k6-full.js

Full stress test — 0→500 VU ramp (staging only)

backend/tests/performance/benchmark_guard_performance.py

SemanticGuard cache performance (pytest)

Test Environment

Demo serverSingle-region cloud · 2 vCPU · 4GB RAM
Test toolk6 (Grafana) + pytest-benchmark
BackendFastAPI + asyncpg + Redis 7 + PostgreSQL 15
Load scenariosSmoke (1 VU) · Load (50 VU) · Stress (200 VU)
Baseline VU count50 VU sustained for 2 minutes
FrequencyBlocking CI gate on every pull request

Production note: Self-hosted on production hardware (4+ vCPU, 8GB RAM) will significantly outperform these demo numbers. Contact us for production benchmark guidance.

Open Benchmarks

Performance questions? Run the tests yourself.

All k6 scripts are in the repo. Run them against the demo API or your own deployment. If you want a production sizing conversation, we are happy to help.