Find out why your LLM prompt cache isn't saving you money.

Prompt caching cuts input cost up to ~90% — but it fails silently. A broken cache still returns correct responses; you just quietly pay full price. cachedoctor tells you whether your cache is working, why it isn't, and how much it's costing you.

Get it on GitHub $ go install github.com/cachedoctor/cachedoctor@latest

Point your app at it. See the leak.

Run observe as a local pass-through proxy and set your SDK's base URL to it. Requests are forwarded unchanged — read-only, any language, key never stored — and every call gets a live diagnosis.

$ cachedoctor observe
$ export ANTHROPIC_BASE_URL=http://localhost:7070   # or OPENAI_BASE_URL
$ python your_app.py

🔴 #1 anthropic /v1/messages → 200 · hit 0%  · No prompt caching enabled
🔴 #2 anthropic /v1/messages → 200 · hit 0%  · New cacheable prefix (drifted?)
── session summary ──
2 requests · hit rate 0% · spent ~$0.42 · recoverable ~$18.30 (this session)
~90%
input-cost discount a working cache earns on the stable prefix — the largest share of most production bills.
$3,000 → $300
per day, for a support bot resending a 10k-token system-plus-tools prefix on 100k calls (Sonnet rates). One stray timestamp keeps you at $3,000.
0 errors
a broken cache throws. The response is still correct — the only symptom is the invoice.

Four commands

One static Go binary. No Python environment, no LLM calls, no telemetry — deterministic rules, runnable air-gapped against logs you already have.

cachedoctor observe

Live proxy: diagnose real traffic as it flows. Anti-patterns, prefix drift between calls, running hit rate, dollars recoverable.

cachedoctor check req.json

Scan one request body for cache anti-patterns — volatile values in the prefix, missing or misplaced breakpoints, below-minimum prefixes, models with no caching at all.

cachedoctor diff a.json b.json

Two consecutive calls that should have hit the cache but didn't? See the exact byte where the prefix identity broke.

cachedoctor analyze usage.jsonl

Point it at response logs you already collect: real hit rate and $/month recoverable, priced per model.

What silently kills a cache

Caching applies wherever the same tokens lead the prompt on consecutive calls — in most production apps that's 80–95% of every request. Every row below has a way to silently break byte-identity.

Use caseWhat silently kills the cache
Support / chat botsa timestamp in the system prompt
Coding agents, IDE assistantsprefix drift between call types
Document Q&Are-serializing the doc per question
RAGshuffled retrieval order
LLM-as-judge / evalsrebuilt few-shot example order
Multi-agent fan-outtools serialized from an unordered map — random per worker
Scheduled batch jobscall cadence longer than the TTL: all writes, no reads
Voice / real-time agentsper-utterance session metadata up top

Gate pull requests on cache regressions

check and diff exit 2 on a high-severity issue — a strict exit-code contract (0 clean · 1 unreadable input · 2 finding · 64 usage error), so a flag typo can never masquerade as a passing build. There's a ready-made GitHub Action that checks saved request bodies, diffs them against the base branch, and comments the impact on the PR.

$ cat req.json | cachedoctor check -

🔴 HIGH — Volatile content in the cached prefix
    Your prompt prefix contains a volatile value (timestamp: "2026-09-14T07:12:03Z").
    The provider caches the longest byte-identical prefix, so anything that changes
    near the front means the cache never engages — silently.
    fix: Move changing values toward the end; keep system and tools byte-stable.

$ echo $?
2
cachedoctord · early access

Diagnosis is free. The fix runs in-flight.

The CLI tells you where the money leaks. cachedoctord is the commercial companion proxy that closes the leaks continuously — and proves the savings on your real traffic.

  • Fixes, not findings. Cache injection, prefix normalization, keep-warm, fan-out serialization, a response cache, and a batch lane — the leak table above, closed in-flight with no application changes.
  • Provable savings. A per-tenant A/B report that separates measured savings from attributed from advisory — the headline number is only what can be proven on your traffic.
  • Your keys never stored. BYOK: credentials pass through per request. Single static Go binary or distroless container, self-hosted in your VPC. Anthropic deep, OpenAI savings-grade, Gemini metering.
Request early access on GitHub

Why cachedoctor