LLM Gateway Bench

June 29, 2026 ยท View on GitHub

Black-box benchmark for LLM API gateways/relays. Don't trust claims, measure behavior โ€” see in 5 seconds how your gateway compares to the best.

๐Ÿ”— Live: https://cuihuan.github.io/llm-gateway-bench/ ยท MIT


โšก TL;DR

What it is โ€” an open-source gateway-benchmark tool + knowledge base: black-box probe any OpenAI-compatible gateway with your own key, compare it to "the best" dimension by dimension, plus a guide on how to choose.

The one question it answers

I just plugged in a gateway โ€” is it any good? Where does it lag the best: price, speed, stability, integrity, or caching?

Self-test in one command

PROBE_KEY=sk-your-key npm run compare -- --model gemini-2.5-flash \
  --url https://your-gateway.com --name "My Gateway" --price-in 0.2 --price-out 1.0
# โ†’ A self-contained report: gap card (you vs best) + price/speed/stability/behavioral fingerprints/cache.
#   Keys never leave your machine.

๐Ÿง  What actually matters when choosing a gateway (in priority order)

DimensionCheck๐Ÿšฉ Red flag
1. Trust & integrityIs it the real model? Will it vanish?Wrong model echo, no legal entity/invoice, suspiciously cheap
2. PriceGateway price รท official price = multiplier<0.5ร— is usually a reverse/pirated channel; inflated token usage
3. Stability30/7-day success rate, peak-hour slowdownShaky uptime, peak TTFT drift โ‰ฅ2ร—
4. SpeedTime-to-first-token (TTFT), throughput tok/sFake streaming (buffers the whole reply, then dumps it at once)
5. CacheDoes a repeated prompt hit the cache?Repeats cost full price (no caching)
CatalogDoes it carry the models and protocols you need?โ€”

Rule of thumb: trust first, price second, speed third. "Too cheap" is a danger sign โ€” always read it alongside trust.


๐Ÿงญ Choosing a Gateway (newbie guide)

Why a gateway/relay โ€” one key, one OpenAI-compatible endpoint for many models; friendlier access/payment (especially in CN); sometimes cheaper or with fallback routing.

They actually come in five flavors (knowing which you want narrows the choice):

  1. Aggregator โ€” many providers, one API and one bill (e.g. OpenRouter).
  2. Relay โ€” resells upstream, usually price-first (this project focuses on their trustworthiness).
  3. Gateway ยท Router โ€” adds policy, logging, rate limiting, per-request model routing (LiteLLM, Portkey, Helicone).
  4. Cloud model-mall โ€” a cloud vendor's catalog with enterprise controls (Bedrock-style).
  5. First-party inference โ€” speed- or price-first inference (Groq, Together, SiliconFlow).

Pitfalls newbies hit (exactly what this project black-box detects):

  • Model substitution / silent downgrade โ€” selling a cheap model under the Claude name.
  • Inflated token usage / hidden injected system prompt โ€” overcharging.
  • Fake streaming โ€” buffers the whole reply then dumps it at once, hiding queue latency.
  • Quantization degradation โ€” routed to INT4/FP4 weights; CJK breaks first.
  • Context truncation โ€” long context silently trimmed to save cost.
  • Exit scam / no invoice โ€” cheap to acquire users โ†’ price hike โ†’ domain vanishes.
  • Hidden fees โ€” e.g. OpenRouter's 5.5% credit-top-up fee.

Full pain-points ร— black-box detection toolbox in docs/research.md; per-dimension methodology in docs/methodology.md.


๐Ÿ›  What you get

Three layers โ€” self-test โ†’ reference leaderboard โ†’ learn how to judge:

โ‘  Tools (run locally, keys stay on your machine)

  • npm run compare โ€” your gateway vs others/best โ†’ a gap card.
  • npm run longcontext โ€” multi-length ร— multi-depth needle test โ†’ a context-truncation heatmap.
  • npm run matrix โ€” classic-model ร— gateway matrix (maintainers run it in CI).

โ‘ก Live explorer (a reference baseline that mirrors the system below) Open https://cuihuan.github.io/llm-gateway-bench/, top to bottom:

  • Pick-for-me โ€” tick what you care about (cheap/stable/fast/compliant) for a transparent recommendation (per-dimension ranking, no hidden weighting).
  • Quick-rank โ€” live re-rank by priority + protocol/type filters + "current #1" highlight.
  • Lenses โ€” ranking / price / stability / behavioral check / summary table โ€” the same list with swappable column sets.
  • Gap check โ€” "test my own gateway" and see how far it lags the best.
  • Report gallery โ€” classic-model ร— gateway matrix, long-context, price comparisons; shareable.
  • Model evals โ€” which model gives the most value (price-value, authoritative benchmarks).

โ‘ข Knowledge base


๐Ÿš€ Quick Start

# Node โ‰ฅ 20, zero deps
git clone https://github.com/cuihuan/llm-gateway-bench && cd llm-gateway-bench
npm test                                   # unit tests

# A) Self-test + gap check: your gateway vs OpenRouter / others
PROBE_KEY=sk-mine OPENROUTER_API_KEY=sk-or AIHUBMIX_API_KEY=sk-ah \
  npm run compare -- --model gemini-2.5-flash \
    --url https://your-gateway.com --name "My Gateway" --price-in 0.2 --price-out 1.0 \
    --with openrouter,aihubmix
# โ†’ reports/<model>-<date>.html (self-contained, shareable)

# B) Long-context retention (multi-length ร— multi-depth needle)
PROBE_KEY=sk-mine npm run longcontext -- --model gemini-2.5-flash \
  --url https://your-gateway.com --lengths 4000,16000,64000 --depths 10,50,90

# C) Serve the live dashboard locally
npm run serve                              # http://localhost:8080

Each run measures: TTFT & throughput (multi-sample percentiles) ยท success rate ยท price multiplier ยท tool-call forwarding ยท fake streaming ยท model echo ยท CJK integrity ยท long-context truncation ยท usage recomputation ยท prompt caching. Red line: keys are read only from environment variables โ€” never written into reports, never leaving your machine.


๐Ÿ“ The Dimensions

Each dimension: what ยท why it matters ยท how it's measured ยท red flag.

  • Trust & integrity โ€” channel origin can't be "proven by claim", so we build a black-box profile from a combination of behavioral fingerprints: model echo (catches substitution), whether tool calls get stripped, fake streaming (per-chunk timing), CJK integrity (a quantization tell), context-truncation needle, usage recomputation (catches inflation); retention/training/legal-entity claims are annotated against terms-of-service text + evidence links. ๐Ÿšฉ Any fingerprint consistently failing / suspiciously cheap / no legal entity or invoice.
  • Price โ€” gateway price รท official price = price index (official price taken from the litellm price library), geometric mean across models. ๐Ÿšฉ >1ร— is pricey; <0.5ร— is usually a reverse/pirated channel; an unusually low charsPerToken = suspected inflated token usage.
  • Stability โ€” 7/30-day rolling success rate, error breakdown (rate-limit 429 โ‰  outage 5xx โ‰  timeout โ€” read separately), latency drift, time-of-day profile (does it slow down at peak?). ๐Ÿšฉ Peak drift โ‰ฅ2ร—, shaky success rate, ban-wave outages.
  • Speed โ€” streaming TTFT p50/p95, throughput tok/s. ๐Ÿšฉ Fake streaming (TTFT โ‰ˆ total latency, then dumped at once).
  • Cache โ€” send the same long prompt twice; check whether the second request's usage reports a cache hit (compatible with OpenAI/DeepSeek/Anthropic conventions). ๐Ÿšฉ Repeated prompts cost full price (unsupported / not reported).
  • Catalog โ€” does it carry the models you need, protocol coverage (OpenAI / Anthropic), model count.

๐Ÿ— How it works โ€” serverless, data-as-repo

GitHub Actions (every 6h cron)
  โ”œโ”€ probe/probe.mjs     black-box probe each gateway ร— model โ†’ data/results/
  โ”œโ”€ probe/prices.mjs    pull public pricing (litellm/synthorai/openrouter) โ†’ data/prices.json
  โ”œโ”€ probe/matrix.mjs    classic-model ร— gateway matrix โ†’ web/reports/matrix-*.json
  โ””โ”€ probe/aggregate.mjs aggregate results + annotations + prices โ†’ web/data.json (+ price matrix)
        โ””โ”€ web/*.html    static render (GitHub Pages); browser & CLI share one render fn
  • No server, no DB โ€” raw data is committed per run; fully auditable and reproducible.
  • Zero keys in repo โ€” keys live only in GitHub Secrets / local environment variables; gateways missing a key are marked skipped, not failed.
  • No black-box score โ€” each dimension is its own column; "Pick-for-me / Quick-rank" maps priorities to transparent per-dimension sorts and shows the per-dimension ranking.

โž• Use it

Add a gateway โ€” PR data/gateways.json (fill in baseUrl, authEnv, probeModels); once the maintainer sets the key in Secrets it automatically enters the probe rotation. To join the classic-model matrix, also add that gateway's model aliases in data/tracked-models.json.

Share a report โ€” copy report.json into web/reports/ and open a PR, or run node scripts/publish-report.mjs <report.json> (auto-archives + verifies there are no leaked keys).

Local high-frequency recorder (macOS) โ€” cp .env.example .env, fill in your key โ†’ ./scripts/install-recorder.sh (a launchd timer probes every 600s to add a local/CN direct-connection viewpoint).

Full contribution rules and trustworthiness invariants are in CONTRIBUTING.md.


๐Ÿ”ญ Landscape & references

Where we sit: user-perspective, black-box, trust-first benchmarking of OpenAI-compatible gateways/relays โ€” serverless, data-as-repo. We borrow ideas from others and build our own.

Companion tools (same author) โ€” to pick a gateway first: awesome-ai-gateway (a curated list + reproducible cost benchmarks + compliance/security scorecards); to just check "is a model live, and how fast": modelprobe (zero-dependency Go prober you drop into CI/cron). This project focuses on black-box probing of gateway behavior with your own key โ€” together the three form a "pick โ†’ benchmark behavior โ†’ probe availability" toolkit.


Fairness ยท Methodology

  • The probe scripts, detection prompts, decision thresholds, raw data, and aggregation logic are all open source โ€” anyone can reproduce them with their own key.
  • The leaderboard has no black-box weighted score; each dimension is its own column. Policy claims must carry an evidence link + date; when missing they are recorded as "โ€”" and never fabricated.
  • When the maintainer has a conflict of interest with a gateway, it is disclosed inline in the entry.

Methodology in brief โ€” every 6h via GitHub Actions, fixed-prompt streaming requests, 3 samples/model reported as percentiles, concurrency โ‰ค4 (this is dial-testing, not load-testing); time-of-day profiling uses real timestamps to account for cron jitter. Full definitions: docs/methodology.md.

License

MIT