Gateway benchmarks
Because speed matters.
We like it fast.
Your AI deserves a fast path. See how Aixy compares in a controlled gateway latency benchmark.
Latest benchmark run:
Less time in the gateway.
- Aixy 0.476 ms
- Bifrost 2.149 ms Aixy −77.84%
- Portkey OSS 7.417 ms Aixy −93.58%
- LiteLLM (Python) 15.551 ms Aixy −96.94%
Aixy configurations
Real controls. Measured overhead.
Compare Aixy with guardrails, budgets and rate limits across input sizes and response protocols.
Controlled Linux benchmark · Lower is better
JSON · 1 KiB · Six configurations
- Default0.465ms95%: 0.462–0.468
- Guardrails0.515ms95%: 0.513–0.517
- Rate limits0.723ms95%: 0.716–0.730
- Hard budgets0.948ms95%: 0.939–0.957
- Guardrails + hard budgets1.001ms95%: 0.987–1.016
- All controls1.337ms95%: 1.306–1.368
Mean of eight block p99s. Intervals are per-condition 95% block intervals.
View all measurements
8 blocks · 36 comparisons · 384 cells · 28,955,691 measured requests, including direct controls.
| Configuration | JSON | SSE | ||||
|---|---|---|---|---|---|---|
| 1 KiB | 16 KiB | 64 KiB | 1 KiB | 16 KiB | 64 KiB | |
| Default | 0.465 | 0.533 | 0.716 | 0.525 | 0.574 | 0.749 |
| Guardrails | 0.515 | 1.075 | 2.831 | 0.575 | 1.116 | 2.843 |
| Hard budgets | 0.948 | 0.989 | 1.174 | 0.989 | 1.002 | 1.192 |
| Guardrails + hard budgets | 1.001 | 1.552 | 3.268 | 1.047 | 1.536 | 3.290 |
| Rate limits | 0.723 | 0.798 | 0.983 | 0.792 | 0.853 | 1.025 |
| All controls | 1.337 | 1.876 | 3.668 | 1.386 | 1.908 | 3.718 |
Sample counts and intervals
All core blocks passed the harness-saturation and direct-control drift checks. Intervals are per-condition 95% block intervals.
| Workload | Configuration | p99 (ms) | 95% block interval (ms) | Requests per block |
|---|---|---|---|---|
| JSON · 1 KiB | Default | 0.465 | 0.462–0.468 | 120,431 · 118,942 · 119,486 · 119,815 · 118,495 · 120,086 · 121,068 · 120,727 |
| JSON · 1 KiB | Guardrails | 0.515 | 0.513–0.517 | 108,525 · 107,889 · 108,218 · 108,315 · 107,682 · 107,965 · 109,377 · 108,109 |
| JSON · 1 KiB | Hard budgets | 0.948 | 0.939–0.957 | 75,204 · 74,695 · 76,155 · 75,883 · 76,150 · 76,395 · 76,297 · 76,001 |
| JSON · 1 KiB | Guardrails + hard budgets | 1.001 | 0.987–1.016 | 69,999 · 70,260 · 70,611 · 70,826 · 70,194 · 71,627 · 71,268 · 71,888 |
| JSON · 1 KiB | Rate limits | 0.723 | 0.716–0.730 | 83,318 · 83,224 · 84,677 · 83,630 · 84,448 · 84,558 · 84,596 · 83,579 |
| JSON · 1 KiB | All controls | 1.337 | 1.306–1.368 | 55,093 · 55,040 · 55,166 · 56,096 · 55,724 · 55,853 · 56,544 · 56,730 |
| SSE · 1 KiB | Default | 0.525 | 0.521–0.528 | 75,728 · 76,018 · 76,275 · 76,211 · 76,678 · 76,864 · 76,194 · 76,456 |
| SSE · 1 KiB | Guardrails | 0.575 | 0.573–0.578 | 71,068 · 71,205 · 71,309 · 71,449 · 71,220 · 71,262 · 71,310 · 71,726 |
| SSE · 1 KiB | Hard budgets | 0.989 | 0.971–1.007 | 54,997 · 55,609 · 55,717 · 55,881 · 55,562 · 56,343 · 56,198 · 56,258 |
| SSE · 1 KiB | Guardrails + hard budgets | 1.047 | 1.032–1.061 | 52,570 · 52,160 · 52,808 · 53,085 · 53,238 · 53,590 · 53,177 · 53,488 |
| SSE · 1 KiB | Rate limits | 0.792 | 0.779–0.805 | 58,970 · 58,850 · 60,085 · 59,977 · 59,973 · 60,330 · 60,401 · 59,620 |
| SSE · 1 KiB | All controls | 1.386 | 1.364–1.409 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| JSON · 16 KiB | Default | 0.533 | 0.529–0.537 | 97,986 · 97,610 · 98,225 · 98,193 · 98,412 · 99,670 · 99,060 · 99,239 |
| JSON · 16 KiB | Guardrails | 1.075 | 1.069–1.082 | 51,312 · 51,195 · 51,307 · 51,473 · 51,612 · 51,665 · 51,650 · 51,701 |
| JSON · 16 KiB | Hard budgets | 0.989 | 0.971–1.006 | 65,959 · 65,863 · 67,019 · 66,918 · 67,315 · 67,224 · 67,274 · 67,094 |
| JSON · 16 KiB | Guardrails + hard budgets | 1.552 | 1.530–1.574 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| JSON · 16 KiB | Rate limits | 0.798 | 0.783–0.813 | 72,726 · 72,695 · 72,769 · 72,353 · 73,446 · 73,021 · 73,334 · 73,969 |
| JSON · 16 KiB | All controls | 1.876 | 1.854–1.897 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| SSE · 16 KiB | Default | 0.574 | 0.571–0.578 | 67,898 · 67,213 · 67,782 · 67,842 · 68,295 · 67,862 · 68,327 · 68,547 |
| SSE · 16 KiB | Guardrails | 1.116 | 1.112–1.121 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| SSE · 16 KiB | Hard budgets | 1.002 | 0.981–1.023 | 50,799 · 50,731 · 51,038 · 51,077 · 51,187 · 51,416 · 51,509 · 51,373 |
| SSE · 16 KiB | Guardrails + hard budgets | 1.536 | 1.519–1.553 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| SSE · 16 KiB | Rate limits | 0.853 | 0.847–0.859 | 53,899 · 53,819 · 54,100 · 54,101 · 54,274 · 54,911 · 54,654 · 54,766 |
| SSE · 16 KiB | All controls | 1.908 | 1.882–1.933 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| JSON · 64 KiB | Default | 0.716 | 0.711–0.721 | 65,416 · 65,168 · 65,717 · 65,451 · 65,814 · 65,647 · 65,857 · 65,679 |
| JSON · 64 KiB | Guardrails | 2.831 | 2.792–2.869 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| JSON · 64 KiB | Hard budgets | 1.174 | 1.166–1.181 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,008 |
| JSON · 64 KiB | Guardrails + hard budgets | 3.268 | 3.223–3.313 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| JSON · 64 KiB | Rate limits | 0.983 | 0.968–0.997 | 52,871 · 52,476 · 53,101 · 52,929 · 53,167 · 53,179 · 53,264 · 53,115 |
| JSON · 64 KiB | All controls | 3.668 | 3.626–3.710 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| SSE · 64 KiB | Default | 0.749 | 0.745–0.753 | 50,405 · 50,639 · 50,817 · 50,630 · 50,682 · 51,036 · 51,019 · 50,924 |
| SSE · 64 KiB | Guardrails | 2.843 | 2.824–2.861 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| SSE · 64 KiB | Hard budgets | 1.192 | 1.179–1.205 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| SSE · 64 KiB | Guardrails + hard budgets | 3.290 | 3.251–3.329 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| SSE · 64 KiB | Rate limits | 1.025 | 1.016–1.034 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
| SSE · 64 KiB | All controls | 3.718 | 3.688–3.748 | 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 · 50,000 |
What each configuration includes
Default includes authentication, pricing and usage tracking. Guardrails enables inline detectors and PII redaction; fixed text inputs exercise the benign path, with enforcement and redaction checked separately before timing. Hard budgets and rate limits exercise organization, project and API-key scopes through Redis. The “All controls” configuration combines guardrails, hard budgets and rate limits.
Core inputs use a fixed text corpus. KiB counts message-content bytes, not tokens or the full HTTP body. SSE measures a streamed response; p99.9 is a descriptive point estimate. CPU covers the response window, with gateway and Redis measured separately.
Workload benchmarks
More demanding workloads.
Compare Default and All controls across larger prompts, conversation history, tool-call payloads and streaming responses.
Exploratory results · Three blocks · No confidence intervals
Large input · 256 KiB · JSON
- Default1.418 ms
- All controls10.641 ms
Measured requests per block
- Default
- 30,274 · 30,059 · 29,630
- All controls
- 10,000 · 10,000 · 10,000
Mean of three block p99s · No confidence intervals
Descriptive full-response diagnostic; the client/loopback baseline is retained.
Large input · 256 KiB · SSE
16 stream frames · 0 ms provider frame interval · 0 ms client read delay
- Default1.414 ms
- All controls10.551 ms
Measured requests per block
- Default
- 26,683 · 26,690 · 26,571
- All controls
- 10,000 · 10,000 · 10,000
Mean of three block p99s · No confidence intervals
Descriptive full-response diagnostic; the client/loopback baseline is retained.
Conversation history · 64 KiB · JSON
- Default0.730 ms
- All controls3.579 ms
Measured requests per block
- Default
- 63,381 · 62,994 · 63,189
- All controls
- 16,607 · 16,476 · 16,496
Mean of three block p99s · No confidence intervals
Descriptive full-response diagnostic; the client/loopback baseline is retained.
Conversation history · 64 KiB · SSE
16 stream frames · 0 ms provider frame interval · 0 ms client read delay
- Default0.764 ms
- All controls3.594 ms
Measured requests per block
- Default
- 49,361 · 49,168 · 49,245
- All controls
- 15,402 · 15,391 · 15,412
Mean of three block p99s · No confidence intervals
Descriptive full-response diagnostic; the client/loopback baseline is retained.
Tool-call payload · 64 KiB · JSON
- Default0.754 ms
- All controls3.590 ms
Measured requests per block
- Default
- 60,722 · 60,577 · 60,476
- All controls
- 16,483 · 16,433 · 16,441
Mean of three block p99s · No confidence intervals
Descriptive full-response diagnostic; the client/loopback baseline is retained.
Tool-call payload · 64 KiB · SSE
16 stream frames · 0 ms provider frame interval · 0 ms client read delay
- Default0.791 ms
- All controls3.656 ms
Measured requests per block
- Default
- 47,914 · 47,535 · 47,583
- All controls
- 15,351 · 15,301 · 15,289
Mean of three block p99s · No confidence intervals
Descriptive full-response diagnostic; the client/loopback baseline is retained.
Slow client (1 ms read delay) · 1 KiB · SSE
64 stream frames · 0 ms provider frame interval · 1 ms client read delay
- Default47.295 ms
- All controls48.457 ms
Measured requests per block
- Default
- 1,249 · 1,249 · 1,248
- All controls
- 1,234 · 1,232 · 1,230
Mean of three block p99s · No confidence intervals
Includes intentional client-read pacing. These results do not isolate gateway latency or establish capacity. Reduced minimum: 100 requests per block. Tail percentiles remain exploratory; inspect the actual sample counts.
Slow client (5 ms read delay) · 1 KiB · SSE
64 stream frames · 1 ms provider frame interval · 5 ms client read delay
- Default161.559 ms
- All controls162.605 ms
Measured requests per block
- Default
- 263 · 263 · 263
- All controls
- 262 · 262 · 262
Mean of three block p99s · No confidence intervals
Includes intentional provider-frame and client-read pacing. These results do not isolate gateway latency or establish capacity. Reduced minimum: 100 requests per block. Tail percentiles remain exploratory; inspect the actual sample counts.
Synthetic PII redaction · 64 KiB · JSON
- Default0.721 ms
- All controls4.263 ms
Measured requests per block
- Default
- 65,717 · 65,058 · 64,924
- All controls
- 14,189 · 14,131 · 14,003
Mean of three block p99s · No confidence intervals
Synthetic email and phone data. Default forwards the original input; All controls applies the configured inline redaction.
What these workloads exercise
Input sizes count message content, not the full HTTP body. Conversation history uses six fixed messages, with most input text in the system message.
Tool-call payloads use five fixed messages containing a prior function call and its result, plus one tool schema. No tools or MCP servers are executed.
View all workload measurements
| Workload | Configuration | p99 (ms) | Requests per block | Diagnostic notes |
|---|---|---|---|---|
| Large input · 256 KiB · JSON | Default | 1.418 | 30,274 · 30,059 · 29,630 | Descriptive diagnostic. Measured requests per block: 30,274, 30,059, 29,630. |
| Large input · 256 KiB · JSON | All controls | 10.641 | 10,000 · 10,000 · 10,000 | Descriptive diagnostic. Measured requests per block: 10,000, 10,000, 10,000. |
| Large input · 256 KiB · SSE | Default | 1.414 | 26,683 · 26,690 · 26,571 | Descriptive diagnostic. Measured requests per block: 26,683, 26,690, 26,571. |
| Large input · 256 KiB · SSE | All controls | 10.551 | 10,000 · 10,000 · 10,000 | Descriptive diagnostic. Measured requests per block: 10,000, 10,000, 10,000. |
| Conversation history · 64 KiB · JSON | Default | 0.730 | 63,381 · 62,994 · 63,189 | Descriptive diagnostic. Measured requests per block: 63,381, 62,994, 63,189. |
| Conversation history · 64 KiB · JSON | All controls | 3.579 | 16,607 · 16,476 · 16,496 | Descriptive diagnostic. Measured requests per block: 16,607, 16,476, 16,496. |
| Conversation history · 64 KiB · SSE | Default | 0.764 | 49,361 · 49,168 · 49,245 | Descriptive diagnostic. Measured requests per block: 49,361, 49,168, 49,245. |
| Conversation history · 64 KiB · SSE | All controls | 3.594 | 15,402 · 15,391 · 15,412 | Descriptive diagnostic. Measured requests per block: 15,402, 15,391, 15,412. |
| Tool-call payload · 64 KiB · JSON | Default | 0.754 | 60,722 · 60,577 · 60,476 | Descriptive diagnostic. Measured requests per block: 60,722, 60,577, 60,476. |
| Tool-call payload · 64 KiB · JSON | All controls | 3.590 | 16,483 · 16,433 · 16,441 | Descriptive diagnostic. Measured requests per block: 16,483, 16,433, 16,441. |
| Tool-call payload · 64 KiB · SSE | Default | 0.791 | 47,914 · 47,535 · 47,583 | Descriptive diagnostic. Measured requests per block: 47,914, 47,535, 47,583. |
| Tool-call payload · 64 KiB · SSE | All controls | 3.656 | 15,351 · 15,301 · 15,289 | Descriptive diagnostic. Measured requests per block: 15,351, 15,301, 15,289. |
| Slow client (1 ms read delay) · 1 KiB · SSE | Default | 47.295 | 1,249 · 1,249 · 1,248 | Descriptive diagnostic. Measured requests per block: 1,249, 1,249, 1,248. Reduced sampling minimum; exploratory tail percentiles. |
| Slow client (1 ms read delay) · 1 KiB · SSE | All controls | 48.457 | 1,234 · 1,232 · 1,230 | Descriptive diagnostic. Measured requests per block: 1,234, 1,232, 1,230. Reduced sampling minimum; exploratory tail percentiles. |
| Slow client (5 ms read delay) · 1 KiB · SSE | Default | 161.559 | 263 · 263 · 263 | Descriptive diagnostic. Measured requests per block: 263, 263, 263. Reduced sampling minimum; exploratory tail percentiles. |
| Slow client (5 ms read delay) · 1 KiB · SSE | All controls | 162.605 | 262 · 262 · 262 | Descriptive diagnostic. Measured requests per block: 262, 262, 262. Reduced sampling minimum; exploratory tail percentiles. |
| Synthetic PII redaction · 64 KiB · JSON | Default | 0.721 | 65,717 · 65,058 · 64,924 | Descriptive diagnostic. Measured requests per block: 65,717, 65,058, 64,924. |
| Synthetic PII redaction · 64 KiB · JSON | All controls | 4.263 | 14,189 · 14,131 · 14,003 | Descriptive diagnostic. Measured requests per block: 14,189, 14,131, 14,003. |
How we measured
Each gateway received one core and 4 GiB of memory on the same arm64 Linux host. Eight balanced blocks used direct-to-provider controls before and after each gateway, with at least 50,000 requests and 60 seconds per cell. Added latency is each client duration minus its matching provider duration, including the client and loopback baseline. Results are the mean of eight block p99s, not a pooled p99; Aixy’s 95% block interval is 0.474–0.479 ms.
Aixy’s native fixture exercises forwarding and usage components. This JSON test compares the configured gateways, including standard Python LiteLLM; it does not measure production or streaming performance. Enabled controls differ by gateway; the download includes their profiles.
The separate Aixy configuration matrix compares six native configurations across fixed 1, 16 and 64 KiB text inputs, JSON and SSE. Its eight near-balanced blocks use grouped direct controls around fresh configuration lifecycles; core results are means of block percentiles. The fixture uses native controls and bounded local usage acknowledgements. The four-gateway comparison above remains a separate campaign. Extended workloads are descriptive three-block diagnostics.