Skip to content

feat: enable Automatic Prefix Caching by default#233

Merged
inureyes merged 2 commits into
mainfrom
feat/issue-228-apc-default-on
Jun 12, 2026
Merged

feat: enable Automatic Prefix Caching by default#233
inureyes merged 2 commits into
mainfrom
feat/issue-228-apc-default-on

Conversation

@inureyes

Copy link
Copy Markdown
Member

Summary

Implements #228, the capstone of the memory-footprint issue set (#224, #225, #226, #227).

With non-consuming clone-and-pin adoption (#227) a partial match shares prefix blocks without copying or destroying the stored entry, and the real-bytes ledger (#226) makes --prompt-cache-capacity-bytes genuinely bound retention, so the reasons to keep APC opt-in are gone. Without APC, a stored prefix is reusable only when fully contained in the new request, which left the default server config unable to reuse KV across requests that share a system prompt but diverge afterwards (the central finding of the cross-version footprint measurement that produced this issue set).

  • Both serve binaries (mlxcel serve, mlx-server) flip --apc-enabled to default true. Disable with --apc-enabled=false; the APC_ENABLED env fallback still applies when the flag is absent (the fallback keys on whether clap actually received the flag, not on the default value). Hybrid SSM models keep the automatic runtime disable.
  • Docs: turbo-kv-cache.md now describes the default paged backend, clone-and-pin adoption, APC partial matching, real-bytes retention accounting, and a measured end-to-end footprint table; CONTINUOUS_BATCHING.md aligned.

Measured (new defaults, no flags, llama-3.2-1b, M1 Ultra, phys-footprint peak during the scenario phase)

scenario v0.1.4 new default cached tokens
idle 957 MiB 983 MiB -
8 concurrent, shared ~3.7k-token prompt 1653 MiB 1627 MiB 29184 (8/8 adopt), phase 3.4x faster
same prefix, 8 sequential 1650 MiB 1413 MiB 25536
multiturn, 8 turns 2104 MiB 1301 MiB 10976
churn, 32 distinct prompts 1558 MiB 2276 MiB 1984

v0.1.4 never engaged the prompt cache from the HTTP path, so it is the no-cache floor; the new default matches or beats it on every sharing scenario while also skipping the shared prefill work. The churn growth is donated-entry retention, now real-bytes-accounted and bounded by the capacity cap (validated in #231: eviction triggers).

Validation

  • cli_help_consistency 10/10 (both binaries agree on the new default).
  • Prefix-share parity suite 7/7 real-model byte-identical (whole, partial, clone-and-pin, unaligned whole-entry).
  • Server lib 3150, cold clippy clean, fmt clean.
  • Acceptance criteria: default mlxcel serve shows cached>0 on burst, seqshare, and multiturn (29184 / 25536 / 10976); shared-prefix scenario footprint at or below the v0.1.4 baseline; scenario walls all at or below v0.1.4 (burst 15.7 s vs 23.0, seqshare 14.0 vs 19.0, multiturn 13.0 vs 14.8); docs carry the measured table.

Closes #228

inureyes added 2 commits June 12, 2026 14:57
With non-consuming clone-and-pin adoption (#227) a partial match shares
prefix blocks without copying or destroying the stored entry, and the
real-bytes ledger (#226) makes the capacity cap genuinely bound
retention, so the reasons to keep APC opt-in are gone. Without APC a
stored prefix is reusable only when fully contained in the new request,
which made the default server config unable to reuse KV across requests
that share a system prompt but diverge afterwards.

Both serve binaries flip --apc-enabled to default true (disable with
--apc-enabled=false; the APC_ENABLED env fallback still applies when
the flag is absent). Hybrid SSM models keep the automatic runtime
disable. Docs updated: turbo-kv-cache.md describes the default paged
backend, clone-and-pin adoption, APC partial matching, real-bytes
retention accounting, and adds the measured end-to-end footprint table
(v0.1.4 vs current default, llama-3.2-1b, M1 Ultra);
CONTINUOUS_BATCHING.md aligned.

Measured on the new defaults (scripts/bench_memory_footprint.py):
8-way shared-prefix burst peak 1627 MiB vs v0.1.4's 1653 with all 8
requests adopting (29184 cached tokens) and the request phase 3.4x
faster; sequential share 1413 vs 1650; multiturn 1301 vs 2104 with
10976 cached tokens; churn retains donated entries (real memory,
governed by --prompt-cache-capacity-bytes). cli_help_consistency 10/10,
prefix-share parity 7/7 real-model, server lib 3150, cold clippy and
fmt clean.
@inureyes
inureyes merged commit 304d0a0 into main Jun 12, 2026
5 checks passed
@inureyes
inureyes deleted the feat/issue-228-apc-default-on branch June 12, 2026 06:10
@inureyes inureyes added this to the 0.2 milestone Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(server): make the default serve config actually reuse prefix KV and validate footprint end-to-end

1 participant