n4nAI

Benchmarks & performance

Analysis

Mistral Large benchmark speed under rate limits

Analyze how rate limits distort Mistral Large benchmark speed measurements, with practical load-testing code and tradeoffs for production inference.

n4n Team5 min read1,139 words

Audio narration

Coming soon — every post will get a voice note here.

Mistral Large benchmark speed rate limits are a recurring source of confusion for teams comparing model providers. The raw generation throughput of Mistral Large 2 is consistent across well-provisioned infrastructure, but the moment you cap requests per minute or tokens per minute, observed latency and tokens-per-second collapse for reasons that have nothing to do with the model itself. This analysis breaks down where the distortion comes from, how to isolate real performance, and what tradeoffs you accept when benchmarking under quota constraints.

How rate limits actually throttle Mistral Large

Most hosted Mistral Large endpoints enforce two independent ceilings: requests per minute (RPM) and tokens per minute (TPM). The TPM counter usually includes both prompt and completion tokens, though some providers bill only input or use sliding windows. When you exceed either, the API returns HTTP 429 with a Retry-After header. The model process never sees your request until the window resets.

That gap is the core distortion. A single-stream benchmark that loops ten requests at 2 RPM against a 1 RPM limit will spend more time sleeping than generating. Your calculated “speed” becomes a function of the limit, not the model.

Worse, many client libraries retry transparently. If you use the OpenAI SDK with default retry, a throttled run silently multiplies wall-clock time and may double-count prompt tokens in your metrics if you re-send the same body. Mistral Large’s 128k context window makes prompt token counts nontrivial; a 4k-token prompt resent five times burns 20k tokens against your TPM quota before a single completion token emerges.

Why Mistral Large benchmark speed rate limits read slower than reality

Consider a 5 RPM / 100k TPM limit. You fire 20 concurrent requests, each with a 2k-token prompt and max_tokens=500. The first five pass; the remaining fifteen get 429s. Your client backs off, waits 12 seconds, retries. The second batch of five passes, another 12-second wait, and so on. Total wall time stretches to ~48 seconds for what should be a 10-second generation burst.

Compute naive throughput: 20 * 500 = 10,000 completion tokens over 48 seconds = 208 tokens/sec across the “system”. But the model itself, once it receives a request, streams at its normal double-digit tokens/sec per stream. The aggregate is low because only five streams ever ran concurrently, and they were interrupted by queuing. The benchmark measures the quota, not the silicon.

This is why published Mistral Large benchmark speed rate limits comparisons from third parties often contradict each other: they differ in concurrency, retry policy, and whether they counted throttled attempts as zero-token failures or excluded them.

Measuring real throughput without the noise

To get a defensible number, you must stay under the limit while saturating the model. Pick a concurrency that fits both RPM and TPM. For a 5 RPM limit and 2k-token prompts with 500 completion tokens, each call consumes ~2.5k TPM. Five concurrent calls per minute use 12.5k TPM, well under 100k. So set max_concurrency = 4 and loop for a fixed duration.

Use the usage object returned by the API; never estimate token counts from string length. The following async snippet runs a bounded concurrent test and reports effective completion tokens per second while honoring 429s with exponential backoff:

import openai, asyncio, time

client = openai.AsyncOpenAI(
    base_url="https://api.mistral.ai/v1",
    api_key="YOUR_KEY"
)

async def call_once():
    backoff = 1.0
    for _ in range(6):
        try:
            resp = await client.chat.completions.create(
                model="mistral-large-latest",
                messages=[{"role":"user","content":"Summarize distributed rate limiting."}],
                max_tokens=400,
            )
            return resp.usage.completion_tokens
        except openai.RateLimitError:
            await asyncio.sleep(backoff)
            backoff *= 2
    return 0

async def main(concurrency, seconds):
    start = time.time()
    completed = 0
    total_tokens = 0
    while time.time() - start < seconds:
        batch = [call_once() for _ in range(concurrency)]
        results = await asyncio.gather(*batch)
        total_tokens += sum(results)
        completed += len(results)
    elapsed = time.time() - start
    print(f"Calls: {completed}, Tokens: {total_tokens}, "
          f"Eff: {total_tokens/elapsed:.1f} t/s, "
          f"Per-call: {elapsed/completed:.2f}s")

asyncio.run(main(concurrency=4, seconds=60))

Run this against a single provider with no intermediary. If you see zero RateLimitError exceptions in logs, you are measuring model speed. If you see any, drop concurrency.

Isolating the first token latency

Generation speed splits into time-to-first-token (TTFT) and inter-token latency. Under rate limits, TTFT inflates because the request sits in a provider queue before scheduling. To measure clean TTFT, send one request at a time with a fresh connection and record resp.created vs local receive time of first chunk. Do not mix this with throughput testing; the numbers answer different questions.

Provider variance and fallback behavior

Mistral Large is available from Mistral’s own platform, Azure AI Studio, and several resellers. Each applies distinct limit shapes. Azure often bundles token limits per deployment tier; Mistral’s platform uses separate RPM and TPM with short reset windows. A gateway that aggregates providers can obscure this.

n4n.ai exposes one OpenAI-compatible endpoint covering 240+ models and applies automatic fallback when a provider is rate-limited or degraded. That feature is excellent for production resilience, but it ruins a controlled Mistral Large benchmark speed rate limits experiment: a throttled call silently reroutes to a different backend with different hardware, and your throughput chart becomes a blend of two providers. When benchmarking, send a routing directive that pins a single upstream and disables fallback, or test the provider directly. It also honors client routing directives and forwards provider cache-control hints, so you can force a specific replica and bypass prefix caching if you need cold-start numbers.

Even without a gateway, providers may shift your request to different replica types behind the same model name during load. The only way to know is to stamp requests with a client id and compare TTFT distributions across the run.

Tradeoffs of benchmarking under constrained quotas

You face a deliberate choice:

  • Test below limits: You learn the model’s intrinsic speed and latency. This is what matters for user-facing streaming UX where you control concurrency.
  • Test at or above limits: You learn your quota’s real-world capacity and retry behavior. This matters for batch jobs or multi-tenant proxies.

Engineers often conflate the two. If you publish “Mistral Large does 20 t/s” from a rate-limited batch run, you understate the model. If you publish “Mistral Large does 200 t/s aggregate” from an unthrottled 50-stream test, you overstate what your production quota will deliver.

The honest tradeoff is time. Proper isolation requires running both regimes and labeling them clearly. Skipping the below-limit run saves an hour and produces a misleading blog post. Skipping the at-limit run ships a system that falls over the first time a second tenant appears.

Sizing concurrency for stable numbers

Use the provider’s documented TPM and RPM to derive a safe concurrency C:

C <= RPM_limit / (calls_per_minute_per_stream)
C <= TPM_limit / (avg_prompt_tokens + avg_completion_tokens) / (calls_per_minute_per_stream)

For streaming, calls_per_minute_per_stream is roughly 60 / avg_latency_seconds. If a single call takes 8 seconds end-to-end, one stream issues 7.5 calls/min; with 5 RPM you can run at most 5/7.5 = 0.66 streams—so concurrency 1. That counterintuitive result explains why low RPM quotas force serial benchmarks and kill aggregate throughput.

Per-token usage metering, as provided by compliant gateways, lets you verify you stayed under TPM. Log usage.total_tokens for every call and sum per rolling minute. If your sum approaches the limit, your “slow” benchmark was just throttled.

Decisive takeaway

Mistral Large benchmark speed rate limits are a measurement artifact, not a model property. To get numbers you can trust, run a below-limit concurrent test with explicit backoff and token counting, then separately run an at-limit stress test to size your quota. Never let a fallback gateway mask throttling unless you are measuring resilience, not speed. If you only read one line: the model is fast; the quota is what’s slow.

Tagsmistral-largerate-limitsinference-speed

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →