# 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
```bash
# macOS / Linux
git clone https://github.com/0x0funky/claude-cache-guard ~/.claude/skills/cache-guard
```
```powershell
# 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
```bash
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`](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