Skip to content

Commit a400fa0

Browse files
committed
2 parents 493bcbb + 4169999 commit a400fa0

19 files changed

Lines changed: 50 additions & 94 deletions

‎results/added_latency.png‎

-138 KB
Loading

‎results/frontier_climb.png‎

-500 KB
Loading

‎results/frontier_rps_at_bound.png‎

-253 KB
Loading

‎results/frontier_shape.png‎

-160 KB
Loading

‎results/frontier_shapes_key.png‎

106 Bytes
Loading

‎results/memory_recovery.png‎

-294 KB
Loading

‎results/memory_rss.png‎

-275 KB
Loading

‎results/reports/all/README.md‎

Lines changed: 31 additions & 61 deletions
Large diffs are not rendered by default.

‎results/reports/top5/README.md‎

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,23 @@
11
# Top 5 gateways (table: lowest added latency; each chart: top 5 by its own metric)
22

3-
**Ran on:** AWS m7g.4xlarge (Graviton3, 16 cores / 64 GB). Gateway-under-test pinned to 4 cores (the comparable basis); mock and load generator on 6 cores each so the mock never bottlenecks the streaming sweep. Ubuntu 24.04. One dedicated box per gateway. · 2026-07-30T02:36:30Z
3+
**Ran on:** AWS m7g.4xlarge (Graviton3, 16 cores / 64 GB). Gateway-under-test pinned to 4 cores (the comparable basis); mock and load generator on 6 cores each so the mock never bottlenecks the streaming sweep. Ubuntu 24.04. One dedicated box per gateway. · 2026-07-30T05:08:25Z
44

55
Every number below is regenerated from the raw `results/*.json` - re-run `run-all.sh` and this page updates. Passthrough and translation figures are the canonical per-gateway records (matrix per-cell sweep, perf/xlate-suite fallback) from `site/data.json`, the same values the site table ranks. Chart bars are **colored by implementation language** (Rust / Go / Python / Node / Other). **Rows are sorted by added latency (p99), lowest first.**
66

77
| Gateway | Added latency (p99) | req/s @ p99 < 10 ms, zero failures | Idle RAM | Steady-state RAM | Built |
88
|---|--:|--:|--:|--:|---|
9-
| [LiteLLM · Rust](https://github.com/BerriAI/litellm) | 106 µs | 44,363 <sub>(+1% from 1 ms to no bound)</sub> | - | - | `litellm-ai-gateway` |
10-
| [agentgateway](https://github.com/agentgateway/agentgateway) | 216 µs | 24,298 <sub>(+7% from 1 ms to no bound)</sub> | 25 MiB | 47 MiB | `ghcr.io/agentgateway/agentgateway:v1.4.0` |
11-
| [AISIX (api7)](https://github.com/api7/aisix) | 267 µs | 17,009 <sub>(+1% from 1 ms to no bound)</sub> | 67 MiB | 349 MiB | `target/release/aisix` |
12-
| [Helicone](https://github.com/Helicone/ai-gateway) | 291 µs | 15,108 <sub>(+5% from 1 ms to no bound)</sub> | 43 MiB | 56 MiB | `target/release/ai-gateway` |
13-
| [Kong](https://github.com/Kong/kong) | 396 µs | 22,659 <sub>(+79% from 1 ms to no bound)</sub> | 378 MiB | 591 MiB | `kong:3.9.3` |
9+
| [One-API](https://github.com/songquanpeng/one-api) | 233,648 µs | 0 | 88 MiB | 144 MiB | `justsong/one-api:v0.6.10` |
1410

1511
**Throughput is a curve, not a number.** The column above is one reading of each gateway's concurrency sweep: the most req/s it carried while 99% of requests finished under **10 ms** and it failed **none** it accepted. The same sweep is published at 5 tail-latency bounds (1 ms, 5 ms, 10 ms, 50 ms, 100 ms) plus with no bound at all, and the shape across them is the comparison that matters: a gateway already at its ceiling at 1 ms is a different machine from one that doubles when given 5 ms. See the frontier-shape chart. **≥** on a number means the sweep's top rung won, so that rate is a floor and no ceiling was established.
12+
**✕** = did not serve under load (0 successful req/s). &nbsp; **0** = came up, but no tested concurrency held p99 &lt; 10 ms while failing none of the requests it accepted.
13+
1614
## The frontier: throughput at each tail you accept
1715

1816
The most req/s each gateway carried while 99% of requests finished under the column's bound **and it failed none it accepted**. Reading left to right is the tradeoff: a row that barely changes gives you its full rate at a tight tail, and a row that climbs steeply is buying throughput with latency. The last column applies no latency bound at all, so it answers only "how much before it starts failing requests". Rates are non-decreasing left to right by construction - relaxing a bound can only add qualifying rungs, never remove one.
1917

2018
| Gateway | p99 &lt; 1 ms | p99 &lt; 5 ms | p99 &lt; 10 ms | p99 &lt; 50 ms | p99 &lt; 100 ms | no bound | at 10 ms: concurrency, observed tail |
2119
|---|--:|--:|--:|--:|--:|--:|---|
22-
| [LiteLLM · Rust](https://github.com/BerriAI/litellm) | 43,876 | 44,363 | 44,363 | 44,363 | 44,363 | 44,363 | c=32, p99 1.12 ms, c=256 broke it |
23-
| [agentgateway](https://github.com/agentgateway/agentgateway) | 22,864 | 24,184 | 24,298 | 24,530 | 24,530 | 24,530 | c=128, p99 8.67 ms, c=256 broke it |
24-
| [AISIX (api7)](https://github.com/api7/aisix) | 16,835 | 17,009 | 17,009 | 17,009 | 17,009 | 17,009 | c=16, p99 1.47 ms, c=128 broke it |
25-
| [Helicone](https://github.com/Helicone/ai-gateway) | 14,409 | 15,108 | 15,108 | 15,108 | 15,108 | 15,108 | c=32, p99 3.32 ms, c=128 broke it |
26-
| [Kong](https://github.com/Kong/kong) | 12,804 | 20,702 | 22,659 | 22,891 | 22,891 | 22,891 | c=64, p99 9.29 ms, c=128 broke it |
20+
| [One-API](https://github.com/songquanpeng/one-api) | 0 | 0 | 0 | 34 | 34 | 36 | - |
2721

2822
**≥** = the sweep's top rung won, so that rate is a **floor** and no ceiling was established. **0** = the sweep ran and no rung held that bound while failing nothing. **n/a** = the record carries no reading at that bound. A **✕** cell names the record's own reason for the absence.
2923

@@ -33,11 +27,7 @@ Every rung of the same sweep the frontier readings above are taken from, summari
3327

3428
| Gateway | req/s at lowest c | peak req/s (at c) | gain (rate × / concurrency ×) | saturates (95% of peak) | p99 at lowest c → at top c | first c that failed a request | top c probed |
3529
|---|--:|--:|--:|--:|--:|--:|--:|
36-
| [LiteLLM · Rust](https://github.com/BerriAI/litellm) | 8,121 at c=1 | 44,299 at c=32 | 5.5× / 32× | c=8 | 140 µs → 5.23 s | c=32768 | c=32768 |
37-
| [agentgateway](https://github.com/agentgateway/agentgateway) | 4,812 at c=1 | 24,489 at c=256 | 5.1× / 256× | c=16 | 248 µs → 44.3 ms | c=1024 | c=1024 |
38-
| [AISIX (api7)](https://github.com/api7/aisix) | 4,107 at c=1 | 16,936 at c=16 | 4.1× / 16× | c=8 | 270 µs → 4.5 s | none | c=32768 |
39-
| [Helicone](https://github.com/Helicone/ai-gateway) | 3,329 at c=1 | 15,091 at c=32 | 4.5× / 32× | c=8 | 323 µs → 16.2 ms | c=128 | c=128 |
40-
| [Kong](https://github.com/Kong/kong) | 4,321 at c=1 | 22,593 at c=256 | 5.2× / 256× | c=64 | 419 µs → 104 ms | c=1024 | c=2048 |
30+
| [One-API](https://github.com/songquanpeng/one-api) | 29 at c=1 | 37 at c=16 | 1.3× / 16× | c=16 | 42.7 ms → 2.96 s | c=8 | c=16 |
4131

4232
A rung that failed a request it had accepted qualifies for **no** frontier reading at any bound, so rate measured at or above the failing concurrency is not throughput the board will publish - the climb chart rules that region off. **none** in that column is a measured result across the whole ladder, not a missing one.
4333

@@ -47,37 +37,33 @@ Same box, same mock, one gateway at a time. Streaming figures are the overhead t
4737

4838
| Gateway | Added TTFT (p99) | Added per-token (p99) | SSE streams | Translated req/s @ p99 &lt; 10 ms, 20 ms model delay |
4939
|---|--:|--:|--:|--:|
50-
| [LiteLLM · Rust](https://github.com/BerriAI/litellm) | 281 µs | ≤ rig resolution | 1,012 (14,724 fps) | n/a |
51-
| [agentgateway](https://github.com/agentgateway/agentgateway) | 347 µs | 37 µs | 501 (12,605 fps) | 22,032 (openai → anthropic) |
52-
| [AISIX (api7)](https://github.com/api7/aisix) | 584 µs | 12 µs | ✕ not measured | 15,964 (openai → anthropic) |
53-
| [Helicone](https://github.com/Helicone/ai-gateway) | 524 µs | ≤ rig resolution | 491 (23,011 fps) | 15,418 (openai → anthropic) |
54-
| [Kong](https://github.com/Kong/kong) | 106.4 ms | 168.7 ms | 652 (29,445 fps) | 21,141 (openai → gemini) |
40+
| [One-API](https://github.com/songquanpeng/one-api) | 793 µs | ≤ rig resolution | 63 (1,507 fps) | n/a |
5541

5642
**✕** cells are measured refusals, not gaps: the gateway was offered the load and could not do the thing (buffered instead of streaming, rejected the Anthropic shape, or has no native key/limit governance). **n/a** = that suite hasn't been run for this gateway yet.
5743

58-
![added_latency](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_added_latency.png?v=202607300452)
44+
![added_latency](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_added_latency.png?v=202607300518)
5945

60-
![frontier_rps_at_bound](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_frontier_rps_at_bound.png?v=202607300452)
46+
![frontier_rps_at_bound](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_frontier_rps_at_bound.png?v=202607300518)
6147

62-
![memory_rss](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_memory_rss.png?v=202607300452)
48+
![memory_rss](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_memory_rss.png?v=202607300518)
6349

64-
![memory_recovery](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_memory_recovery.png?v=202607300452)
50+
![memory_recovery](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_memory_recovery.png?v=202607300518)
6551

66-
![rps_per_dollar](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_rps_per_dollar.png?v=202607300452)
52+
![rps_per_dollar](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_rps_per_dollar.png?v=202607300518)
6753

68-
![cost_per_million](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_cost_per_million.png?v=202607300452)
54+
![cost_per_million](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_cost_per_million.png?v=202607300518)
6955

70-
![stream_added_ttft](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_stream_added_ttft.png?v=202607300452)
56+
![stream_added_ttft](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_stream_added_ttft.png?v=202607300518)
7157

72-
![stream_added_gap](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_stream_added_gap.png?v=202607300452)
58+
![stream_added_gap](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_stream_added_gap.png?v=202607300518)
7359

74-
![stream_sustained](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_stream_sustained.png?v=202607300452)
60+
![stream_sustained](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_stream_sustained.png?v=202607300518)
7561

76-
![xlate_frontier_rps_at_bound](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_xlate_frontier_rps_at_bound.png?v=202607300452)
62+
![xlate_frontier_rps_at_bound](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_xlate_frontier_rps_at_bound.png?v=202607300518)
7763

78-
![xlate_added_latency](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_xlate_added_latency.png?v=202607300452)
64+
![xlate_added_latency](https://raw.githubusercontent.com/GetBusbar/benchmarking/main/results/top5_xlate_added_latency.png?v=202607300518)
7965

8066
---
8167
Method: added latency = gateway p99 − direct-to-mock p99 at concurrency 1; a frontier reading = the highest req/s any probed concurrency carried while 99% of requests finished under the STATED bound and the gateway failed none it accepted (readings are published at 1, 5, 10, 50, 100 ms and with no bound; the columns above use 10 ms, and every caption names the bound it used); cost figures divide that 10 ms reading by $0.1632/hr for the pinned 4-core (m7g.xlarge) slice; RSS idle = after first 200, steady state = the level the RSS settled at under load. Same box, same mock, same load, one gateway at a time. Each gateway's source ref is pinned in its own `gateways/<name>/definition.json`; the built commit is in each row.
8268

83-
<sub>Page + charts regenerated **2026-07-30 04:52 UTC** from the raw `results/*.json`.</sub>
69+
<sub>Page + charts regenerated **2026-07-30 05:18 UTC** from the raw `results/*.json`.</sub>

‎results/rps_per_dollar.png‎

-157 KB
Loading

0 commit comments

Comments
 (0)