> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aireserve.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Gateway latency benchmark

> How much latency AI Reserve adds on top of calling the provider directly, measured side by side with OpenRouter and Vercel AI Gateway on the same models, the same providers, from the same client.

A gateway earns its place by adding capabilities without adding noticeable latency. We
measure ours the hard way: the same request, to the same model at the same provider, sent
through each gateway and to the provider directly, interleaved from one client, and we
publish the paired difference. The method, the numbers and the raw data are below.

## What is measured

* **Two surfaces, one model each.** Anthropic Messages with Claude Sonnet 4.6 served by
  Anthropic, and OpenAI Responses with GPT-5.5 served by OpenAI: the two wire formats every
  gateway in the comparison serves, so the provider side is identical for every target.
* **Pinned providers.** Each gateway is asked for the same upstream provider by its own
  routing controls (for example OpenRouter's `provider.order` with `allow_fallbacks: false`),
  so no target wins by routing to a different host.
* **Two numbers per target.** For streaming requests, time to the first text token (TTFT).
  For non-streaming requests, total time to the complete response. Both from the client's
  side, from the moment the request is sent.
* **Paired overhead, with its uncertainty.** In every round each target is called once in
  random order. A gateway's overhead is the median, over all rounds, of its time minus the
  direct provider call's time in the same round, which cancels the provider's own
  minute-to-minute drift. Each median is published with a 95% confidence interval
  (1.58 × IQR ÷ √rounds, the notched box-plot rule). A median that does not clear its own
  interval is labelled **within noise**: the run cannot tell that gateway apart from calling
  the provider directly, in either direction.
* **Small output, by design.** `max_tokens: 32` and the prompt "Reply with exactly one
  word: pong." keep generation time short, so the numbers measure the path, not the model.
* **One client.** A GitHub-hosted runner in the US East region, warm-up request per target
  excluded. The number of rounds is stated with each run (60 per mode for runs from
  2026-10-18 on; the first published run used 20). More rounds narrow the intervals and
  steady the medians.

## Results

Run of 2026-10-18 (UTC), 60 rounds per mode, `max_tokens: 32`, targets: Anthropic directly, OpenAI directly, AI Reserve, OpenRouter, Vercel AI Gateway.

**Anthropic Messages, Claude Sonnet 4.6 at Anthropic**

Overhead added on top of calling the provider directly (median of paired rounds, ± its 95% confidence interval):

| Gateway | Stream, to first token | Non-stream, total |
| - | - | - |
| AI Reserve | +101 ±30 ms | +105 ±28 ms |
| OpenRouter | within noise (−4 ±40 ms) | +44 ±31 ms |
| Vercel AI Gateway | +162 ±62 ms | +199 ±64 ms |

"Within noise" means the median does not clear its own interval: the run cannot tell that gateway apart from calling the provider directly, in either direction.

Absolute latency from the runner, p50 (p95), and the fastest single round:

| Target | Stream, to first token | Non-stream, total |
| - | - | - |
| Anthropic directly | 728 (1006) ms, best 580 | 775 (1115) ms, best 618 |
| AI Reserve | 816 (1158) ms, best 650 | 868 (1342) ms, best 714 |
| OpenRouter | 697 (1048) ms, best 568 | 842 (1267) ms, best 669 |
| Vercel AI Gateway | 910 (1244) ms, best 610 | 980 (2166) ms, best 754 |

Model ids as sent: Anthropic directly `claude-sonnet-4-6`, AI Reserve `claude-sonnet-4-6`, OpenRouter `anthropic/claude-sonnet-4.6`, Vercel AI Gateway `anthropic/claude-sonnet-4.6`.

**OpenAI Responses, GPT-5.5 at OpenAI**

Overhead added on top of calling the provider directly (median of paired rounds, ± its 95% confidence interval):

| Gateway | Stream, to first token | Non-stream, total |
| - | - | - |
| AI Reserve | +132 ±38 ms | within noise (+39 ±42 ms) |
| OpenRouter | +466 ±60 ms | +225 ±54 ms |
| Vercel AI Gateway | +73 ±50 ms | −69 ±36 ms |

Absolute latency from the runner, p50 (p95), and the fastest single round:

| Target | Stream, to first token | Non-stream, total |
| - | - | - |
| OpenAI directly | 750 (1225) ms, best 528 | 1007 (1335) ms, best 700 |
| AI Reserve | 885 (1228) ms, best 642 | 1053 (1370) ms, best 818 |
| OpenRouter | 1196 (1609) ms, best 970 | 1249 (1458) ms, best 916 |
| Vercel AI Gateway | 836 (1195) ms, best 604 | 947 (1299) ms, best 739 |

Model ids as sent: OpenAI directly `gpt-5.5`, AI Reserve `gpt-5.5`, OpenRouter `openai/gpt-5.5`, Vercel AI Gateway `openai/gpt-5.5`.

## Reading the numbers

* **Overhead** is what the gateway adds; the p50 and p95 columns include the provider's own
  latency, which dominates both.
* **A negative median is not, by itself, the gateway beating the provider.** A request
  through a gateway travels one more hop than a direct call, and the best rounds in the table
  show roughly what that hop costs: a gateway's fastest round is usually tens of milliseconds
  behind the provider's fastest. The sign of a median can come from the tail instead. A
  provider's own response time varies by a second or more from one request to the next, the
  pairing does not cancel that, and a run in which a few more slow responses happen to land
  on the direct calls tips the median negative. The interval says whether that happened. A
  negative median inside its own interval is within noise, and the honest reading is that the
  gateway added nothing the run could measure. One that clears its interval is a real but
  small effect, pooled already-open connections to the provider and a network path that
  happens to be shorter than the client's, and it is worth tens of milliseconds, not
  hundreds.
* **p95** shows tail behavior over a short run and moves between runs; the medians and their
  intervals are the stable comparison.
* The runner sits in one US region. A client in Europe or Asia sees different absolute
  numbers for every target, but the gateway overheads move together.

## What is not in this table

* **Other gateways.** The comparison covers the gateways that serve both surfaces above with
  provider pinning. We add a gateway when we can run it under the same rules, from the same
  client, with a production key.
* **Other models.** The two surfaces above are the ones every target serves identically.
  Per-model latency across our own catalog is a different question, answered per model in
  the [catalog](/models) and in your own usage analytics.

## Reproduce it

Everything a run needs is on this page: the prompt, `max_tokens`, the model id sent to each
target, the provider-pinning rule, the interleaving and the paired-median definition. Send
the same request to each target from one client, alternate the order every round, and take
the median of the per-round differences together with its interval (1.58 × IQR ÷ √rounds).
We keep the raw per-request samples of every
published run (round, target, mode, status, time to first token, total time) and will share
them, or run the same harness against your own region or model mix, on request in your
shared Slack channel.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.