← back to Exo
Strip Claude headers to improve prefix cache hit rates (#1552)
423ed0f07f706b0555547a0f3512ea0402221207 · 2026-02-19 18:29:34 +0000 · rltakashige
## Motivation
Our hits are really bad at the moment (0.2%). This PR makes it 98.5% on
average.
## Changes
Also adds an example for how to run Claude using Exo.
## Why It Works
Claude sends some billing and session headers that change with each
message.
## Test Plan
### Manual Testing
Works in manual testing.
Files touched
M src/exo/master/adapters/claude.pyA tmp/config_examples/claude_code.sh
Diff
commit 423ed0f07f706b0555547a0f3512ea0402221207
Author: rltakashige <rl.takashige@gmail.com>
Date: Thu Feb 19 18:29:34 2026 +0000
Strip Claude headers to improve prefix cache hit rates (#1552)
## Motivation
Our hits are really bad at the moment (0.2%). This PR makes it 98.5% on
average.
## Changes
Also adds an example for how to run Claude using Exo.
## Why It Works
Claude sends some billing and session headers that change with each
message.
## Test Plan
### Manual Testing
Works in manual testing.
---
src/exo/master/adapters/claude.py | 19 +++++++++++++++++++
tmp/config_examples/claude_code.sh | 8 ++++++++
2 files changed, 27 insertions(+)
diff --git a/src/exo/master/adapters/claude.py b/src/exo/master/adapters/claude.py
index d9d52496..d5246bbc 100644
--- a/src/exo/master/adapters/claude.py
+++ b/src/exo/master/adapters/claude.py
@@ -1,6 +1,7 @@
"""Claude Messages API adapter for converting requests/responses."""
import json
+import re
from collections.abc import AsyncGenerator
from typing import Any
@@ -61,6 +62,22 @@ def _extract_tool_result_text(block: ClaudeToolResultBlock) -> str:
return "".join(sub_block.text for sub_block in block.content)
+# Matches "x-anthropic-billing-header: ...;" (with optional trailing newline)
+# or similar telemetry headers that change every request and break KV prefix caching.
+_VOLATILE_HEADER_RE = re.compile(r"^x-anthropic-[^\n]*;\n?", re.MULTILINE)
+
+
+def _strip_volatile_headers(text: str) -> str:
+ """Remove Anthropic billing/telemetry headers from system prompt text.
+
+ Claude Code prepends headers like 'x-anthropic-billing-header: cc_version=...;
+ cc_entrypoint=...; cch=...;' that contain per-request content hashes. These
+ change every request and break KV prefix caching (the prefix diverges at ~20
+ tokens instead of matching thousands of conversation tokens).
+ """
+ return _VOLATILE_HEADER_RE.sub("", text)
+
+
def claude_request_to_text_generation(
request: ClaudeMessagesRequest,
) -> TextGenerationTaskParams:
@@ -73,6 +90,8 @@ def claude_request_to_text_generation(
instructions = request.system
else:
instructions = "".join(block.text for block in request.system)
+
+ instructions = _strip_volatile_headers(instructions)
chat_template_messages.append({"role": "system", "content": instructions})
# Convert messages to input
diff --git a/tmp/config_examples/claude_code.sh b/tmp/config_examples/claude_code.sh
new file mode 100755
index 00000000..685d0a27
--- /dev/null
+++ b/tmp/config_examples/claude_code.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# Run Claude Code against a local exo cluster! (Here, GPT OSS 120B)
+ANTHROPIC_BASE_URL="http://localhost:52415/" \
+ ANTHROPIC_AUTH_TOKEN="dummy" \
+ ANTHROPIC_MODEL="mlx-community/gpt-oss-120b-MXFP4-Q8" \
+ ANTHROPIC_SMALL_FAST_MODEL="mlx-community/gpt-oss-120b-MXFP4-Q8" \
+ CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
+ claude
← ed001f24 remove prefillprogress event (#1550)
·
back to Exo
·
feat: Mac Studio en2 RDMA port warning v2 (#1551) 94b2ce69 →