Skip to the content.

The 4x that’s real

Short answer. On a realistic 50-turn, 5-agent session, fak’s fused kernel does ~4.1x less work than a tuned single-tenant stack that already has a warm per-agent KV cache. There is a bigger number in the same benchmark — 60.3x — and it is also real, but it is measured against the naive re-prefill-every-turn pattern, and leading with it would be the exact move that makes a perf-literate reader stop trusting you. This page tells the 4.1x honestly: what it is, what it is not, and the conditions it holds under.

For anyone weighing whether fak’s reuse story is worth it on a self-hosted fleet. By the end you will know which baseline the honest number is measured against, why the tuned number is the one to quote, and where the flattering number comes from. Every figure here is witnessed against SESSION-VALUE-STACK-RESULTS.md and indexed in BENCHMARK-AUTHORITY.md.

The setup (what was measured, on what box)

The benchmark (cmd/sessionbench) runs a fixed multi-agent workload on Apple M3 Pro (6P+6E, 36 GB unified), model Qwen2.5-1.5B-Instruct at Q8_0, pure-Go forward pass, native go run. The session shape is the “50+ turns, 5+ agents” regime the agent-serving claim actually needs:

Three arms run the same bit-identical Q8 forward pass — the only difference is which work is reused versus redone:

arm what it models the work it pays
A — naive-stateless a stateless API / llama-cli -p <full prompt> each turn re-prefills the whole context every turn (O(T²))
B — per-agent-KV (tuned) a careful single-tenant stack: prompt-cache / persistent KV per agent prefix once per agent, incremental ingestion, serial decode
C — fak fused prefix prefilled once + cloned into C agents, batched decode, incremental ingestion prefix once total; one weight stream serves all C

The result

metric value
arm A (naive-stateless) 68,726 s (computed from measured prefill curve)
arm B (per-agent-KV, tuned single-tenant) 4,697 s
arm C (fak fused) 1,139 s
net value-add vs tuned single-tenant (B/C) 4.1x
net value-add vs naive (A/C) 60.3x
turn-tax (A/B) 14.6x

The 4.1x is B/C — fak versus a stack that already has a warm KV cache. It comes from two levers stacked together: prefix reuse (the 2048-token preamble is prefilled once, not five times) and decode batching (one weight stream serves all five agents instead of five serial streams), while each agent keeps ownership of its own KV span.

What the 4.1x is not

Why not lead with the 60.3x

The 60.3x (A/C) is a faithful measurement against the naive pattern — one process per agent, re-prefilling the full context every turn, no batching. That pattern is real; it is exactly what a hand-rolled llama-cli -p <full prompt> loop does. But a reader who knows serving will immediately divide the naive re-prefill away as a strawman, and if that was your headline you have lost them. The 4.1x survives that scrutiny because its denominator is a stack that already did the obvious thing. Telling the tuned number first is the credibility move — it is what makes every other number on the page believable.

How honest is the arm-A number?

Arm A’s O(T²) re-prefill is intractable to run fully at 50×5 (~hours on a 1.5B CPU forward pass), so it is computed from prefillCost(L) sampled live at lengths across the session — which captures prefill attention’s real O(L²) growth (at L=2816 the measured cost is 2.9x a linear extrapolation from L=256, so a linear model would badly under-price it). A -validate pass runs arm A fully live at small scale and confirms the projection: anchored_computed_over_live = 1.004, decode_A_over_B = 1.001. Arms B and C are fully live. So the flattering direction (arm A) is the one that is checked hardest against a live run — the opposite of inflation.

The floor that does not depend on any of this

The reuse stack is the ceiling. The floor is the engine-agnostic trust property: on the same box, fak turntax --suite turntax-airline records injections admitted to context 1 → 0 and destructive ops executed 1 → 0, verdicts the model did not author, reproducible on any backend. The happy-path control (turntax-happy) saves exactly 0 — the anti-inflation gate. A 50-turn session derailed by one poisoned tool result is total waste; the floor is what keeps the saved work real instead of confidently wrong. That floor holds even when you call a hosted API and get none of the 4.1x.

Reproduce it

# headline — Qwen2.5-1.5B, 50 turns × 5 agents (realistic model)
FAK_WORKERS=6 go run ./cmd/sessionbench \
  -hf <qwen2.5-1.5b-instruct-snapshot> -lean \
  -turns 50 -agents 5 -prefix 2048 -decode 32 -result 64 \
  -out experiments/session/headline-qwen-50x5.json

# the bit-identity gates the whole value-stack rests on
go test ./internal/model/ -run 'TestBatchedDecodeMatchesSerial|TestBatchFromPrefixMatchesIndependentPrefill' -count=1

Honest fences


Related: SESSION-VALUE-STACK-RESULTS.md (the full benchmark, arms, and witnesses) · the cache cliff (why the prefix-reuse win exists at all) · BENCHMARK-AUTHORITY.md (the central claim ledger).

Dimension H (Benchmark-as-story) of the concept-popularization epic.