claude-cache-guard

A Claude Code skill that stops prompt-cache thrash — the hidden cost pattern where reading one screenshot inside a long conversation rewrites the entire conversation history at 12.5× the cache-read price.

Measured results

Real image-heavy production workload, same project / model / day, comparable work batches, before vs after applying the rules:

Metric Before After Δ
Images read in main context 40 (across 22 turns) 1
Cache writes (billed at 1.25×) 18.0M tok 0.74M tok −96%
Output tokens (work produced) 139k 164k +18%
Quota-weighted consumption 27.6M eq-tok 3.4M eq-tok −88%
Estimated cost $276.80 $33.65 −88%
Consumption per unit of output 199 20.5 ≈10× efficiency

Same model, same image resolution, same output quality. (Honest caveat: a real-workload before/after, not a variable-controlled A/B; the "after" also starts from a fresh context — which is itself one of the rules, R6.)

What it does

When Claude is about to read images/screenshots in a session with history — visual QA, render checks, UI verification, diagram review — the skill loads rules that make it:

  1. Batch all image reads into a single message (1 image or 10 = same rewrite cost)
  2. Write findings to a notes file and never re-read an unchanged image
  3. Delegate vision checks to a subagent with a tiny isolated context, so the main session's cached prefix is never invalidated
  4. Keep large tool outputs (build logs, file dumps, base64) out of context
  5. Avoid TTL-expiry wakes and mid-session model/tool changes that nuke the cache

Plus a read-only audit script that ranks your recent sessions by estimated cost and flags exactly which calls thrashed the cache and why.

Install

# macOS / Linux
git clone https://github.com/0x0funky/claude-cache-guard ~/.claude/skills/cache-guard
# Windows (PowerShell)
git clone https://github.com/0x0funky/claude-cache-guard "$env:USERPROFILE\.claude\skills\cache-guard"

Project-scoped alternative: clone into <repo>/.claude/skills/cache-guard/.

New Claude Code sessions pick it up automatically (model-invoked via its description, or explicitly with /cache-guard). Already-running sessions see it after starting a new conversation.

Using CLAUDE_CONFIG_DIR for multiple accounts? Clone into each config dir's skills/ as well.

Audit your own burn

node ~/.claude/skills/cache-guard/scripts/audit-session.mjs             # last 5h
node ~/.claude/skills/cache-guard/scripts/audit-session.mjs --hours 24
node ~/.claude/skills/cache-guard/scripts/audit-session.mjs --detail <sid8>

Requires Node 18+. Local-only, read-only, no telemetry — it parses the transcripts Claude Code already writes on your machine and prints aggregates.

Output flags:

Flag Meaning Fix
IMG-REWRITE an image invalidated the messages-tier cache → full history rewrite rules R1 / R3
TTL-WAKE session idled >5 min; wake rewrote the whole context rule R6
DUP-IMG same image read more than once rule R2

Health grades: OK = write:read ≥ 1:10 · WARN ≥ 1:3 · BAD < 1:3.

How it works (the one-paragraph version)

The prompt cache is a prefix match over tools → system → messages. Per Anthropic's prompt-caching docs, the presence/absence of images anywhere in the prompt invalidates the messages tier; the rewrite bills at 1.25× input price versus 0.1× for reads — a 12.5× spread. In a big session that spread — not the images themselves — is where the money goes: in the measured case the 40 images were ~23k tokens of content but triggered 16M+ tokens of history rewrites (≈700× overhead). Full math and the worked example: references/mechanism.md.

Repository layout

SKILL.md                  # the skill — rules R1–R6 + decision table
references/mechanism.md   # cache tiers, pricing math, worked example
scripts/audit-session.mjs # session forensics tool

License

MIT