System prompts grow the way configuration files do: every incident adds an instruction, every edge case adds an example, and nothing is ever deleted. Unlike a config file, though, this one is billed per request. Take a 5,000-token system prompt on Claude Sonnet 5 at standard pricing ($3 per million input tokens): that is $0.015 of fixed overhead per request — $15,000 a month at one million requests, before a single user token is processed. If half of those 5,000 tokens are redundant, the audit described below is worth $7,500 a month. And with prompt caching (cache reads at 0.1x input price, $0.30 per million on Sonnet 5), the same prompt costs about $1,500 a month — which is why the audit has two goals: make the prompt shorter, and make it cacheable.
Step 1: measure before judging
The token counting endpoint is free and accepts exactly what message creation accepts — system prompt, tools, messages — so you can weigh each component separately. It is stateless: to price a candidate edit, count both versions and subtract.
from anthropic import AnthropicVertex
client = AnthropicVertex(project_id="my-project", region="global")
count = client.messages.count_tokens(
model="claude-sonnet-5",
system=open("system_prompt.txt").read(),
messages=[{"role": "user", "content": "ping"}],
)
print(count.input_tokens) # weigh the prompt itself
Count against the model you actually run: Sonnet 5, Fable 5, and Opus 4.7+ use a newer tokenizer that produces roughly 30% more tokens for the same text than earlier generations, so numbers measured on an old model understate today's cost. Don't use OpenAI's tiktoken as a proxy — it undercounts Claude tokens significantly.
Step 2: hunt the four classic wastes
Redundant instructions. Prompts accumulate near-duplicates ("be concise", "keep answers short", "avoid unnecessary detail") and instructions restating model defaults. Anthropic's own guidance favors clear, direct instructions with the reason attached — one well-motivated sentence outperforms three overlapping ones, and costs less.
Example bloat. Few-shot examples are the heaviest block in most prompts. The documented sweet spot is 3–5 relevant, diverse examples wrapped in <example> tags; auditing often finds ten near-identical ones. Cut duplicates and verify with your eval suite that quality holds.
Stale context. Policy text for features that shipped, warnings about model behaviors fixed two generations ago, tool guidance for tools no longer registered. Anything that references a date, version, or system that no longer exists is a deletion candidate.
Tool definition overhead. Tools bill as input tokens too: enabling tool use adds a system-prompt overhead of a few hundred tokens (for example, 354 tokens on Sonnet 5 with auto tool choice), the bash tool definition adds 325 tokens on Opus 4.7/4.8, and the text editor tool adds 700. Every verbose tool description and unused registered tool rides along on every request — trim schemas and unregister what the workload never calls.
Step 3: make what remains cache-friendly
After shrinking the prompt, ensure it actually caches. Caching is a strict prefix match on exact bytes, so common patterns silently break it: timestamps or request UUIDs interpolated into the system prompt, non-deterministic JSON serialization of tool definitions, per-user tool sets, and conditional sections that differ between requests. Move anything dynamic after the cached breakpoint (or into the user message). Remember the hierarchy — tools, then system, then messages — a change to tool definitions invalidates everything downstream. Also check the minimum: prompts below the model's cacheable floor (1,024 tokens on Opus 4.8, Sonnet 5, and Haiku 4.5; 512 on Fable 5) won't cache at all, which occasionally means a very short prompt is fine to leave uncached.
Where to go next
Pair this audit with system prompt caching ROI and cache hit rate strategy. For the writing side, see prompt engineering for enterprises; for trimming the conversation itself, multi-turn compression.