Methodology

Every number on this site comes from bench/runner.py in the site's repository. The harness is about 350 lines of dependency-free Python, and it is the same file on every machine — no per-machine tweaks, because a benchmark you edit per machine is not a benchmark.

What is measured

The harness talks to an OpenAI-compatible /v1/chat/completionsendpoint and times the response stream from the client side. Measuring client-side is deliberate: llama.cpp, ollama, vLLM and MLX all report internal statistics differently, and some do not report them at all. Timing the stream is the only method that produces numbers comparable across all of them.

How runs are conducted

The four scenarios

ScenarioInOutWhat it exposes
chat_short128256Interactive feel; latency-dominated
chat_long_context8192256RAG and long-document work
code_generation5121024Agentic coding; decode-dominated
summarization16384128Worst case for weak prefill

Scenarios are frozen. Adding one is fine; editing an existing one would silently invalidate every previously published comparison, so it does not happen.

What these numbers are not

Single-stream benchmarks. They describe one person using one model interactively — the actual local-LLM use case — and they say nothing about throughput under concurrent load, where batching changes the picture entirely. They also reflect specific driver, backend and model versions, all recorded in each result file. A rerun six months later on the same hardware can legitimately produce different numbers, which is why the backend version is published alongside every result.

Reproducing them

# On the machine under test, with a server already running:
python3 bench/runner.py \
  --url http://localhost:11434 \
  --model llama3.1:8b \
  --label my-machine \
  --quant Q4_K_M

The result lands in data/runs/ as JSON. Those files are the primary record — the tables on this site are rendered from them at build time, so a published number and its source file cannot disagree.