Benchmarks
Claims, measured.
Every number on this page was produced by a runnable harness with pinned fixtures. Labels say what was measured and what was not.
generated 2026-06-11 · tolkin 0.11.0 · prices 2026-06 · 3 runs
Claimed vs. Measured
The gap is the point.
Published claims from upstream READMEs, run against the same declared fixtures, same tokenizer, same one-command harness. The difference is denominator choice, not fabrication.
Achieved-versus-claimed is denominator-sensitive: repomix's claim is whole-repo packs with tree-sitter-strippable bodies, this corpus is three small files chosen to keep the fixture reviewable. Run...
The cross-reference review (REVIEW-FINDINGS.md) flagged the 46 percent memory-store figure as unverified at the gap-1 surface and the upstream README's about-75-percent prose figure has no publishe...
Label key
- measuredRun on the same fixtures, same tokenizer.
- not-runnableCannot be run headlessly; reason in the comparisons table below.
Track 1
Structural
losslessWhitespace normalization, comment stripping, and format conversions applied to real-world fixtures. All savings are lossless: semantic content is preserved exactly. Deterministic transforms must show zero variance across runs; the harness treats any deviation as a failure.
| Case | Technique | Tokenizer | Before | After | Saved | Pct | Variance |
|---|---|---|---|---|---|---|---|
| app-config.json | JSON.parse / JSON.stringify (compact) | o200k_base (exact) | 1,305 | 882 | 423 | 32.4% | stable |
| marketing-page.html | HTML -> Markdown (audit preview rules) | o200k_base (exact) | 1,111 | 539 | 572 | 51.5% | stable |
| duplicated-paragraphs.txt | exact-text paragraph dedup (first-occurrence kept) | o200k_base (exact) | 793 | 441 | 352 | 44.4% | stable |
| stack-trace.log | stack-trace dump dedup (replace identical body with marker) | o200k_base (exact) | 2,022 | 1,442 | 580 | 28.7% | stable |
Track 2
Configuration
lossless-configEvery MCP server in a client configuration contributes its tool definitions to every request. This track counts that weight using real, vendored tools/list manifests captured live from public servers and tokenized with o200k_base. Cold is the tokenized weight of the tool definitions, no price multipliers. Swap savings replace a server with a CLI equivalent; slim savings are the measured difference between two tokenized manifests.
| Case | Basis | Tokenizer | Tools | Cold tokens | Swap savings | Slim savings | % of 200K |
|---|---|---|---|---|---|---|---|
| server-filesystem | tokenized-manifest | o200k_base (exact) | 14 | 1,641 | 1,641 | 0 | 0.8% |
| server-memory | tokenized-manifest | o200k_base (exact) | 9 | 904 | 0 | 0 | 0.5% |
| server-everything | tokenized-manifest | o200k_base (exact) | 13 | 1,126 | 0 | 0 | 0.6% |
| github-mcp-server | tokenized-manifest | o200k_base (exact) | 43 | 8,175 | 8,175 | 3,222 | 4.1% |
| github-mcp-server-slim | tokenized-manifest | o200k_base (exact) | 27 | 4,953 | 4,953 | 0 | 2.5% |
| notion-mcp-server | tokenized-manifest | o200k_base (exact) | 22 | 15,698 | 0 | 0 | 7.8% |
Manifest provenance
- configuration/server-filesystem: https://github.com/modelcontextprotocol/servers (src/filesystem), npm @modelcontextprotocol/server-filesystem@2026.1.14; secure-filesystem-server 0.2.0 (package 2026.1.14); captured 2026-06-10; MIT per npm package.json (repo LICENSE records the MIT to Apache-2.0 transition); vendored at fixtures/configuration/manifests/LICENSE-modelcontextprotocol-servers.
- configuration/server-memory: https://github.com/modelcontextprotocol/servers (src/memory), npm @modelcontextprotocol/server-memory@2026.1.26; memory-server 0.6.3 (package 2026.1.26); captured 2026-06-10; MIT per npm package.json (repo LICENSE records the MIT to Apache-2.0 transition); vendored at fixtures/configuration/manifests/LICENSE-modelcontextprotocol-servers.
- configuration/server-everything: https://github.com/modelcontextprotocol/servers (src/everything), npm @modelcontextprotocol/server-everything@2026.1.26; mcp-servers/everything 2.0.0 (package 2026.1.26); captured 2026-06-10; MIT per npm package.json (repo LICENSE records the MIT to Apache-2.0 transition); vendored at fixtures/configuration/manifests/LICENSE-modelcontextprotocol-servers.
- configuration/github-mcp-server: https://github.com/github/github-mcp-server, release v1.2.0 (Darwin arm64 asset); github-mcp-server 1.2.0, default toolsets; captured 2026-06-10; MIT; vendored at fixtures/configuration/manifests/LICENSE-github-mcp-server.
- configuration/github-mcp-server-slim: https://github.com/github/github-mcp-server, release v1.2.0 (Darwin arm64 asset); github-mcp-server 1.2.0, GITHUB_TOOLSETS=repos,issues; captured 2026-06-10; MIT; vendored at fixtures/configuration/manifests/LICENSE-github-mcp-server.
- configuration/notion-mcp-server: https://github.com/makenotion/notion-mcp-server, npm @notionhq/notion-mcp-server@2.2.1; notion-mcp-server 2.2.1, default toolset (no env vars set); captured 2026-06-10; MIT (Copyright (c) 2025 Notion Labs, Inc.); vendored at fixtures/configuration/manifests/LICENSE-notion-mcp-server.
External comparisons
| Tool | Before | After | Savings | Notes |
|---|---|---|---|---|
| caveman-shrink | 27,544 | 27,024 | 1.89% | Input-side effect of lossy description rewriting on real manifests; tool names and schemas untouched. No quality claim: shrunken descriptions are not evaluated for selection accuracy. |
- wilpel/caveman-compressionnot-runnable
MIT-licensed and exposes a Python CLI (caveman_compress_nlp.py) that runs offline, but it requires a Python virtual environment plus the spaCy en_core_web_sm model (~50 MB) which this bun-only harness does not provision. Comparable measurements can be added by running caveman_compress_nlp.py on the same manifest descriptions externally and amending this file.
- notion-slimnot-runnable
MIT-licensed, but the npm tarball at notion-slim@2.0.0-slim.1.10 only ships Windows binaries (bin/mcpslim.exe and bin/mcpslim-windows-x64.exe); index.js references mcpslim-darwin-arm64 and mcpslim-linux-x64 paths that are not in the tarball, the GitHub repository has no published releases, and the transformation runs inside a closed-source binary. This bun-on-macOS/Linux harness cannot exercise the slim transformation headlessly, and substituting a hand-built approximation of the recipe (recipes/notion.json grouping the 22 upstream tools into 10) is forbidden by the methodology. To verify externally: install notion-slim@<version> on Windows, capture its tools/list with the same JSON-RPC handshake as fixtures/configuration/manifests/capture.ts, vendor it next to notion-mcp-server.tools.json, add it to the configuration cases, and re-run the harness; the achieved saved percent will land next to the catalog's about-52-percent figure.
Track 3
Lossy
lossyLLMLingua-2 compression at declared target ratios, measured on real prose fixtures. Every case publishes both the target ratio and the achieved ratio. Quality scoring is off by default and requires your own API key.
Aggressive compression can increase total cost because outputs grow; every number here is input-token bounded.
| Case | Technique | Target ratio | Before | After | Achieved ratio | Savings |
|---|---|---|---|---|---|---|
| technical-explainer.txt | LLMLingua-2 | 0.70 | 809 | 543 | 0.67 | 32.9% |
| technical-explainer.txt | LLMLingua-2 | 0.50 | 809 | 388 | 0.48 | 52.0% |
| technical-explainer.txt | LLMLingua-2 | 0.33 | 809 | 252 | 0.31 | 68.8% |
| meeting-notes.txt | LLMLingua-2 | 0.70 | 906 | 633 | 0.70 | 30.1% |
| meeting-notes.txt | LLMLingua-2 | 0.50 | 906 | 458 | 0.51 | 49.5% |
| meeting-notes.txt | LLMLingua-2 | 0.33 | 906 | 312 | 0.34 | 65.6% |
| verbose-instructions.txt | LLMLingua-2 | 0.70 | 922 | 622 | 0.67 | 32.5% |
| verbose-instructions.txt | LLMLingua-2 | 0.50 | 922 | 440 | 0.48 | 52.3% |
| verbose-instructions.txt | LLMLingua-2 | 0.33 | 922 | 292 | 0.32 | 68.3% |
Quality scoring
scored=false. Method: BYOK extraction-QA harness, off by default (reason: --score-quality flag not passed (default off))
External comparisons
| Tool | Before | After | Savings | Notes |
|---|---|---|---|---|
| caveman-shrink | 2,637 | 2,328 | 11.72% | Single fixed-rule pass per fixture; no model, no API key, no training data. The methodology section explains why this number is not directly comparable to LLMLingua-2's rate-targeted runs. |
| repomix | 3,200 | 1,745 | 45.47% | Achieved-versus-claimed is denominator-sensitive: repomix's claim is whole-repo packs with tree-sitter-strippable bodies, this corpus is three small files chosen to keep the fixture reviewable. Run on a larger fixture and the saved percent moves; the published number is what the same one-command harness produces on the declared corpus in this tree. |
| cavemem | 2,637 | 2,327 | 11.76% | The cross-reference review (REVIEW-FINDINGS.md) flagged the 46 percent memory-store figure as unverified at the gap-1 surface and the upstream README's about-75-percent prose figure has no published methodology. This row is the measurement: bench fixtures, same tokenizer, same one-command harness as the other comparisons. |
- wilpel/caveman-compressionnot-runnable
MIT-licensed and exposes a Python CLI (caveman_compress_nlp.py) that runs offline, but it requires a Python virtual environment plus the spaCy en_core_web_sm model (~50 MB) which this bun-only harness does not provision. Comparable measurements can be added by running caveman_compress_nlp.py on the lossy fixtures externally and amending this file.
Methodology
How the numbers are made.
The full methodology text below is generated by the same harness that produces the numbers. It is the single source of truth shared by this page and RESULTS.md.
Why this benchmark exists
Token-savings claims usually arrive as a single number, and that number can come from three different places: output-side advice (instructions that make a model answer more tersely), input-side rewriting (compressing the text before it is sent), and structural or configuration measurement (removing tokens from files and tool definitions without changing meaning). These are different operations with different risks and different baselines. Collapsing them into one headline percent is how this space lies to itself.
The cautionary example is public. A viral output-side skill (JuliusBrussee/caveman) claimed a 65 percent average output reduction. An independent 72-run benchmark (Guzik, https://dev.to/jakguzik/i-benchmarked-the-viral-caveman-prompt-to-save-llm-tokens-then-my-6-line-version-beat-it-2o81) measured 9-21 percent output token reduction against a plain no-brevity-instruction baseline. The gap was not fabrication; it was baseline choice. The lesson is baselines, not villains, and this benchmark is designed so the baseline question can never be left open.
The design answer is separation. Every number below belongs to exactly one of three tracks (structural, configuration, lossy), each with its own fidelity contract, and numbers are never blended across tracks into a combined figure.
The rules
Declared baselines. Every comparison states exactly what the before is: a named fixture in the repository, byte for byte, never an implied or reconstructed one.
Real tokenizer counts. Each number names the tokenizer that produced it: o200k_base counts are exact, while Anthropic counts via the cl100k proxy are labeled estimates, carry a plus or minus 10 percent band, and never appear in headline rows.
Injection overhead counted. Any technique that requires runtime prompt instructions has those instruction tokens charged against its savings.
N runs with variance. Every case runs N times and publishes min and max; deterministic transforms must show zero variance, and the harness fails loudly if one does not.
Date-stamped pricing. Every dollar figure carries the PRICES_OBSERVED date it was computed under, because prices move and an undated cost cannot be checked.
Everything in the repository. Fixtures, runner, and results are versioned together, and a single command regenerates all of them.
Input-token bounded. A pre-registered randomized trial (arXiv 2603.23525) found that moderate compression (ratio 0.5) cut total cost 27.9 percent while aggressive compression (ratio 0.2) increased total cost 1.8 percent because outputs grew; every number here is therefore input-side only and says so wherever it appears.
Track 1: structural (lossless)
This track measures transforms that cannot change meaning: minification, exact-duplicate removal, and format transforms, applied to fixtures shaped like real working material (pretty-printed JSON configuration, HTML documents, prompts with repeated boilerplate, stack-trace logs). Because the transforms are lossless by construction, there is no quality question to answer, and the before and after counts are exact properties of the fixtures under the named tokenizer. This is measurement, not estimation.
Track 2: configuration (MCP)
Every MCP server in a client configuration contributes its tool definitions to every request, whether or not the conversation uses them. This track counts that weight against a catalog of real, public server manifests: each fixture is a vendored tools/list output captured live from a named server version (provenance, capture commands, and license texts live next to the fixtures in `fixtures/configuration/manifests/`), tokenized through the real CLI path with o200k_base (exact). Every tool is canonicalized to compact `{name, description, input_schema}` JSON before counting, so the numbers are reproducible byte for byte; a specific client's wire bytes can differ by a few tokens, and that caveat ships in the analyzer output itself. Cold is the tokenized weight of the tool definitions with no provider price multipliers. Swap deltas (replacing a server with a CLI equivalent) derive from the tokenized cold. Slim deltas are the measured difference between two tokenized manifests (the server captured with and without its slim setting) where a slim capture exists; a slim percentage estimate is never applied to a measured cold, because that would blend bases. The tolkin analyzer's curated catalog estimates still exist as a product surface for configs without manifests, and they are labeled as estimates there; they no longer produce benchmark rows. The three earlier config-shape fixtures are retired from this track for exactly that reason, and config-shape parsing is covered by the analyzer's unit tests instead. Only the configuration changes; conversation content is untouched. Comparable middleware (caveman-shrink) runs on the same manifests, headlessly, with measured before and after counts. External claims that can be partially measured (notion-slim claims 52 percent against the full Notion MCP) ship the half that is publicly obtainable (the full Notion manifest measured here) and a not-runnable-headless row with the precise reason the other half cannot be obtained from this platform (notion-slim's npm tarball ships only Windows binaries despite claiming cross-platform support).
Track 3: lossy (compression)
The caveat leads this track: the randomized trial cited above showed that aggressive input compression can grow outputs enough to increase total cost, so no lossy result here is a total-cost claim. The technique measured is LLMLingua-2 at declared target ratios, and every case publishes both the target ratio and the achieved ratio. Quality scoring exists as an extraction-QA harness (questions with verifiable answers, checked automatically) implemented in `lib/scoring.ts` against author-declared QA fixtures at `fixtures/lossy/scoring/
What this benchmark does not claim
No total-cost claims: every figure is input tokens, and total cost depends on output behavior this harness does not measure. No output-side claims: nothing here measures how a model answers. No quality claims without the scored flag: a compression ratio is not a quality result, and results state explicitly whether the extraction-QA harness ran. No numeric comparisons against tools that cannot be run headlessly on the same inputs: those tools appear in the results with a status and a reason instead of numbers, because a figure produced under different conditions is not a comparison.
Reproducing the results
Clone the repository, run `bun install` at the root, build the release `tolkin` binary (`cargo build --release` in `apps/tolkin-cli`), and run the benchmark harness in `apps/tolkin-cli/benchmarks/`; it regenerates `results.json` and `RESULTS.md` from the fixtures in the same directory. Then run it a second time and diff the two outputs: the only field permitted to differ between runs on the same tree is the `generated_at` timestamp. Anything else is a determinism failure, and the harness treats it as one.
### One-command scored run (BYOK)
To publish a scored lossy run (a `scored=true` track with per-case extraction accuracy), the owner runs the same harness with one extra flag and one extra env var:
```
ANTHROPIC_API_KEY=
```
What this does, step by step:
1. The harness builds every track exactly the way `bun apps/tolkin-cli/benchmarks/run.ts` does (structural, configuration, lossy compression).
2. For every lossy case, the runner captures the compressed text produced by LLMLingua-2 and passes it, plus each question from the matching `fixtures/lossy/scoring/
3. The grader is purely deterministic: `lib/scoring.ts` lowercases and whitespace-normalizes both the model's reply and the author-declared accepted answers, then accepts the reply when it equals or contains an accepted answer. There is no LLM-as-judge.
4. The track-level `quality_scoring` field becomes `{ scored: true, grader_model: "claude-opus-4-7", anthropic_version: "2023-06-01", method: ... }` and every lossy case gains a `scored` object with `questions_total`, `questions_correct`, `accuracy`, and the full per-question answers.
5. `--check-determinism` is mutually exclusive with `--score-quality`: live Claude calls are not byte-for-byte deterministic, and the contract is that the deterministic mode runs without scoring and scoring is a separate owner action.
Override the grader model via the env var `TOLKIN_BENCH_SCORE_MODEL=