Skip to content
Benchmarks · P12, 2026-09-27

Measured, not promised.
About half the cost per task — and cheaper on every task we ran.

312 live runs with Claude Opus 5.5 and hidden tests the agent never saw. The context engine and the prompt cache cut the cost of an accepted task by 49% — and every number on this page comes straight from the run logs.

Cost per accepted task−49%A $0.0405 → C $0.0205 · main set, 240 runs
Cost per accepted task, harder set−48%A $0.0543 → C $0.0284 · 72 runs
Turns with the context engine−18%3.05 → 2.50 average · B vs A
A warm, cached request−95%$0.0248 cold → $0.0012 warm
01 · Cost

The headline,
cost per accepted task by arm

Arm C — the context engine plus the prompt cache — costs about half of the baseline on both sets, at the same acceptance.

Cost per accepted task, by arm

Total measured cost ÷ runs accepted by hidden tests. Same model, same machine, same tasks.

Main set: 240 runs, $8.37 total. Harder set: 72 runs, $3.22 total. Arm R was not run on the harder set.

Data table
ArmMain setHarder set
A · Baseline$0.0405$0.0543
B · + context engine$0.0376$0.0513
C · + context engine + cache$0.0205$0.0284
R · + research helpers$0.0409not run

Every task got cheaper — main set

Mean cost per run of each task (3 repeats), baseline A against arm C. Sorted by baseline cost.

  • A · Baseline
  • C · context engine + cache
Data table
TaskSetA meanC meanChange
h9_py_long_repairheld-out$0.0641$0.0422-34%
h11_py_roundingheld-out$0.0605$0.0344-43%
h12_node_format_bytesheld-out$0.0524$0.0245-53%
h3_node_empty_romanheld-out$0.0481$0.0415-14%
h5_py_word_countheld-out$0.0474$0.0224-53%
h8_node_missing_testheld-out$0.0470$0.0259-45%
h6_py_public_typeheld-out$0.0469$0.0205-56%
h2_py_large_repoheld-out$0.0424$0.0121-71%
t7_node_featuretuning$0.0400$0.0226-44%
h4_node_medianheld-out$0.0395$0.0163-59%
t8_py_missing_testtuning$0.0389$0.0183-53%
t4_py_kvtuning$0.0355$0.0149-58%
t6_py_empty_fizzbuzztuning$0.0343$0.0241-30%
h1_py_leapheld-out$0.0340$0.0092-73%
t2_py_discounttuning$0.0324$0.0207-36%
t1_node_slugtuning$0.0322$0.0164-49%
h7_node_configheld-out$0.0302$0.0174-42%
t3_py_configtuning$0.0297$0.0099-67%
h10_py_concurrent_editheld-out$0.0282$0.0089-69%
t5_py_addtuning$0.0267$0.0083-69%

Every task got cheaper — harder set

Mean cost per run of each task (3 repeats), baseline A against arm C. Sorted by baseline cost.

  • A · Baseline
  • C · context engine + cache
Data table
TaskSetA meanC meanChange
x4_py_vat_symptomharder$0.0914$0.0381-58%
x3_node_semverharder$0.0772$0.0480-38%
x8_py_roman_strictharder$0.0516$0.0329-36%
x7_py_compat_renameharder$0.0483$0.0243-50%
x1_py_lruharder$0.0452$0.0242-47%
x2_py_csvharder$0.0435$0.0198-54%
x6_node_debounceharder$0.0423$0.0257-39%
x5_py_intervalsharder$0.0349$0.0145-58%
02 · Why it's cheaper

Same prompt size,
most of it read back from the cache

The context engine keeps the prompt small; the cache means the stable part is paid for once and read back at a twentieth of the price.

Where each run's input tokens come from

Mean input tokens per run, split into fresh input, tokens written to the cache, and tokens read back from it.

  • Fresh input
  • Cache write (billed 1.25×)
  • Cache read (billed 0.05×)

Prompt tokens include cached reads and writes; they are split here, never added twice. Billing ratios from ADR 0010.

Data table
Set · armInputFreshCache writeCache read
Main · A6,5846,58400
Main · B6,3396,33900
Main · C6,34171,3784,955
Main · R6,8036,80300
Harder · A8,6488,64800
Harder · B8,3908,39000
Harder · C8,86681,6577,200

What one request costs, cache by cache

Six live requests to anthropic/claude-opus-5.5 via OpenRouter (2026-09-26), measured with the provider's own cost field.

A cache marker is required — there is no implicit cache. Writes bill at 1.25×, reads at 0.05×; the measured costs match those ratios.

Data table
ScenarioPrompt tokensCache readCache writeCost
No cache marker (same request twice)3,62500$0.0146
Marked, cold4,93104,927$0.0248
Marked, warm (same request)4,9314,9270$0.0012
Later content changed, prefix the same4,9311,7673,160$0.0163
Prefix changed (full miss)4,93804,934$0.0248
Breakpoint on a tool result, then continue6,0015,9820$0.0014
03 · Quality and speed

Nothing got worse:
every run accepted, fewer turns, similar time

Accepted by hidden tests: 312 of 312 runs

Each square is one run (three repeats per task and arm). Filled = the hidden tests passed on the final tree.

  • Accepted

Every arm passed every task, so these sets cannot separate the arms on quality. We don't claim the arms are equal in general — only that none was worse than the baseline here.

Data table
GroupArmAccepted
Main set · tuning (8 tasks)A24/24
Main set · tuning (8 tasks)B24/24
Main set · tuning (8 tasks)C24/24
Main set · tuning (8 tasks)R24/24
Main set · held-out (12 tasks)A36/36
Main set · held-out (12 tasks)B36/36
Main set · held-out (12 tasks)C36/36
Main set · held-out (12 tasks)R36/36
Harder held-out set (8 tasks)A24/24
Harder held-out set (8 tasks)B24/24
Harder held-out set (8 tasks)C24/24

Turns per run — the context engine needs fewer

Share of the 60 main-set runs per arm that finished in 1, 2, 3 or 4 model turns. Mean on the right.

  • 1 turn
  • 2 turns
  • 3 turns
  • 4 turns

Published: average turns 3.05 → 2.50 with the context engine (B vs A, −18%). Means here are computed from the evidence log.

Data table
Arm1234Mean turns
A · Baseline064593.05
B · + context engine0361862.50
C · + context engine + cache3321872.48
R · + research helpers0104192.98

Time to finish, every run

Wall-clock seconds per run, one dot per run (jittered vertically). Ticks show the published median and p90.

  • One run
  • Median
  • p90

Speed was not the goal of the context engine or the cache; medians stay within a few seconds across arms.

Data table
Set · armRunsMedian sp90 sFastest sSlowest s
Main · A6017338.846.6
Main · B6016316.838.0
Main · C6017306.937.5
Main · R6017347.842.0
Harder · A24194111.357.1
Harder · B2417358.839.1
Harder · C2416408.841.6

How we measured
pre-registered, then run

The protocol and its thresholds were written down before any result was seen; results are reported as they came out.

A

Baseline

The P5 baseline agent, unchanged: no context engine and no cache markers.

B

+ context engine

A Rust engine parses the project with tree-sitter, builds a symbol graph and sends the model only the definitions a task needs.

C

+ context engine + cache

B, plus provider cache markers on the stable prefix (tools + system) and a moving breakpoint on the latest message.

R

+ research helpers

A plus research tools the model may call. It never called them in 60 runs, so no benefit could be measured — it stays off.

Model
anthropic/claude-opus-5.5 through OpenRouter, in every arm
Machine
One Mac (macOS 26.6, arm64); same tools and verifier for every run
Main set
20 tasks — 8 tuning, 12 held-out — × 4 arms × 3 repeats = 240 runs (2026-09-27)
Harder set
8 new held-out tasks (LRU eviction, RFC 4180 CSV, SemVer precedence, a symptom-only bug in a 200-file repo …) × 3 arms × 3 = 72 runs
Acceptance
Hidden tests the agent never sees, run on the final tree in a container with no network
Task validity
Hidden tests fail on every original project and pass on every reference solution
Cost
Total measured cost ÷ accepted runs, from the provider's own cost field
Rule, fixed before running
An arm can't become the default if it is worse than A on more than one held-out task
Spend
$8.37 for the main set, $3.22 for the harder set
Limits

What we did not measure

A benchmark is only as honest as its edges. These are ours.

  • Any other product. There is no comparison with Cursor, Claude Code, Codex or anyone else — only our own baseline.
  • Any other model. Every run used Claude Opus 5.5; other models were not measured here.
  • Quality differences. Every arm passed every task (312 of 312), so these sets can't tell the arms apart on quality.
  • Large, multi-step work. Tasks are small and medium; a much bigger set would be needed to see quality gaps.
  • RAM and CPU during live agent runs. Only the core engine's memory was measured, in a local soak with no model calls.
  • Statistical confidence of the success rate — undefined at this sample size.

Questions
about the numbers

Why compare against your own baseline instead of other tools?
Because it isolates one thing: what the context engine and the cache change, with the same model, machine, tasks and verifier. A cross-product comparison would mix in different models, prompts and UIs. We haven't run one, so we don't claim one.
Is the 49% saving on every task, or an average?
It's total cost divided by accepted runs. Per task, arm C's mean cost was lower than the baseline's on all 20 main-set tasks and all 8 harder tasks — the dumbbell charts above show each one.
Does the cache change the answers?
No. Cache markers don't change the request content; a test checks the text is identical. A prefix change simply misses the cache once and the answer stays correct — that's the 'full miss' row in the ladder.
Why is arm R in the table if it was never used?
It was part of the pre-registered protocol, so its result is reported as it came out: the model never called the research helpers in 60 runs. They stay off by default.
Can I reproduce it?
The task set lives in the engine (crates/rift-engine/src/bench.rs), runs are started with scripts/live-p5.sh and summarised by scripts/bench-report.py. Each run is one JSON line in the evidence logs this page is drawn from.
See how the context engine works

About half the cost per task.
Same model, every run accepted.