claude-code-cache-fix: a local proxy that repairs Claude Code prompt cache misses
Fixes prompt cache regression in Claude Code that causes up to 20x cost increase on resumed sessions
At a glance
- What is it?
- claude-code-cache-fix sits between Claude Code and the Anthropic API and rewrites request structure to stop repeated cache_creation_input_tokens spikes. It is a targeted repair for a measurable billing problem, not a general Claude Code enhancement.
- Who is it for?
- Adopt claude-code-cache-fix only after you have measured your own transcripts and found a sustained low cache-read ratio or creation spikes on every --resume. Skip it if your long sessions already hold a high read ratio, if you rarely resume, or if you refuse to put a local process in the API path.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The billing symptom this project exists to repair
Claude Code bills prompt cache reads and cache writes differently, and Claude Code records both per request in its own session transcripts. When a resumed or long-running session keeps re-creating the prompt cache instead of reading it, the same conversation is paid for repeatedly at the expensive rate. The README frames the worst case as up to a 20x cost increase on resumed sessions, and the project's own diagnosis is narrower than that headline: it is a request prefix that does not stay stable, so the cache key changes and the previous cache entry is never hit.
The intended user is someone under quota pressure on long or resumed sessions, not every Claude Code user. The README is unusually direct about this and lists four reasons to skip the project: a stable high cache-read ratio, rare long resumes, no quota pressure, or an unwillingness to place a local proxy in the API path. That last one is a design position, not a bug, and the project treats it as legitimate.
There is also a second surface. The README mentions non-cache symptoms: TTL 5m downgrades, thinking-desync 400 responses, and image-retry storms. Those are handled by the same proxy pipeline rather than by a separate tool.
How the proxy pipeline rewrites requests
The architecture is a local HTTP proxy. Claude Code is pointed at it, and it forwards to Anthropic. On the default path the README states it makes no other outbound calls, and telemetry is written to local files under ~/.claude/ rather than sent anywhere. Two features do perform their own egress and both are off unless enabled: OAuth refresh via CACHE_FIX_OAUTH_REFRESH=on, which posts to Anthropic's token endpoint, and forward-proxy download acceleration, which re-issues release downloads to downloads.claude.ai and storage.googleapis.com.
The proxy can read and rewrite POST /v1/messages. The README is explicit that this capability is the cache repair and that there is no working version without it. What it normalizes is request structure: block order, fingerprint, and TTL. It does not modify the conversation. The README describes it as idempotent, meaning a request that needs nothing passes through unmodified.
Each transform lives in one file under proxy/extensions/, which the README presents as the reason the behaviour is auditable. That is the strongest structural argument for the design: rather than one opaque rewrite step, the pipeline is a set of small units you can read individually. The trade-off is that the proxy still sees your message bodies, and the README does not pretend otherwise.
Forward-proxy mode, enabled with --remote-control, is a different posture. It terminates TLS for api.anthropic.com using a locally generated CA that your client must trust, and everything else is blind-tunnelled. That mode is opt-in and off by default. If you are not using Remote Control, you do not need it.
Measure your cache hit rate before you install anything
The README's best contribution is a diagnostic that does not require the project. Claude Code already writes per-request cache accounting into its session transcripts, so you can compute a read ratio from files you already have. The command below is quoted from the README; it deduplicates by requestId because Claude Code writes multiple transcript rows per request and not always the same number of times per request.
jq -r 'select(.message.usage.cache_read_input_tokens != null) |
"\(.requestId)\t\(.message.usage.cache_read_input_tokens) \(.message.usage.cache_creation_input_tokens)"' \
~/.claude/projects/*/<session-uuid>.jsonl |
sort -u -k1,1 | cut -f2 |
awk '{n++; r+=$1; c+=$2}
END {if (n==0) print "no usage rows found — check the session path";
else printf "requests=%d cache_read=%d creation=%d read-ratio=%.0f%%\n", n, r, c, 100*r/(r+c)}'Replace the session UUID, or use a glob to pick your most recent session. The output is a request count, the summed read and creation token counts, and a read ratio percentage. If the script prints that no usage rows were found, the session path is wrong rather than the cache being healthy.
The README gives two interpretation rules that matter more than the number itself. Fewer than roughly 20 requests makes the ratio meaningless, because a cold start has nothing to read yet and every healthy session looks broken. And the deduplication is not cosmetic: the README cites two sweeps of local transcripts on one machine dated 2026-08-02 where over half of sessions under 20 requests shifted by a point or more without dedup, with a worst case of 41 points. Long sessions were almost all sub-point. Short sessions are exactly what a first-time reader will run this against, so the failure mode is easy to hit.
Installing the proxy and pointing Claude Code at it
The README's recommended path is the proxy, and it states that the proxy works with any Claude Code version, including the v2.1.113+ Bun binary. Node.js 18 or newer is required per package.json. The package installs globally and exposes a binary named cache-fix-proxy.
npm install -g claude-code-cache-fixStart the proxy server. The README shows it running on localhost port 9801.
node "$(npm root -g)/claude-code-cache-fix/proxy/server.mjs" &After that, Claude Code has to be routed through the proxy. The Dockerfile documents the reverse-proxy wiring as an environment variable in the shell that runs claude.
export ANTHROPIC_BASE_URL=http://127.0.0.1:9801
claudeThe health endpoint is the fastest confirmation that the process is alive and in the mode you expect. In forward-proxy mode the Dockerfile notes that curl -s localhost:9801/health must show "forward_proxy":true. If you are in reverse-proxy mode, that field should not be true.
Container users have a documented path as well. The image runs as uid 1000, and the Dockerfile warns that a fresh named volume mounts root-owned, so forward-proxy mode needs a chown'd bind mount so the host can read the generated CA.
mkdir -p ./cache-fix-ca && sudo chown 1000:1000 ./cache-fix-ca
docker run -d -p 9801:9801 --name cache-fix-proxy \
-e CACHE_FIX_FORWARD_PROXY=on \
-e CACHE_FIX_CA_DIR=/ca -v "$PWD/cache-fix-ca:/ca" \
ghcr.io/cnighswonger/claude-code-cache-fix:latestThe Dockerfile also notes that openssl is required by forward-proxy mode to generate the MITM CA, and that without it forward-proxy silently falls back to reverse-proxy. A silent fallback is a bad failure mode for a feature you explicitly turned on: check /health rather than assuming the flag took effect.
Where the design costs you something
The honest limitation is the one the README states first: a local process sits in the API path and can read and rewrite POST /v1/messages. The project argues this is unavoidable and the README agrees that declining it is a good reason not to install. If your threat model does not include a local Node process handling your prompts, this project is not for you, and no amount of extension-file readability changes that.
Forward-proxy mode raises the cost further. It terminates TLS for api.anthropic.com with a locally generated CA that your client must trust, and the Dockerfile's silent fallback to reverse-proxy when openssl is missing means a misconfigured container can appear to work while running a different mode than you intended. Verify with /health.
The measurement advice has its own trap. The README says a session under about 20 requests produces a meaningless ratio, yet short sessions are the most likely thing a new user will test against. Run the diagnostic on a long or resumed session or you will draw the wrong conclusion in either direction.
Finally, the project is not a fix for Claude Code itself. It is a proxy that normalizes requests on the way out. If Anthropic changes the API surface or Claude Code changes how it constructs requests, the proxy has to keep up. The README's own advisory section is evidence of that churn: defaults flipped in v4.0.0, and hot-reload became opt-in behind CACHE_FIX_HOT_RELOAD=on.
Alternatives, and what the difference actually is
The realistic alternative is doing nothing and managing quota instead. The README's own advisory for Opus 4.7 is a concrete example: metered data cited there shows 4.7 burning Q5h quota at roughly 2.4x the rate of 4.6 for equivalent visible token counts, attributed to a new tokenizer and adaptive thinking overhead. The suggested workaround is CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1, which the README says reduces burn by about 3.3x but may reduce quality on complex tasks.
That is a fundamentally different approach. claude-code-cache-fix tries to stop paying for the same prefix twice; the environment-variable workaround tries to generate fewer tokens in the first place. They are not substitutes, and the README presents them as separate levers. If your problem is cache misses on resume, the env var does not address it. If your problem is raw token volume on Opus 4.7, the proxy does not address that either.
The other alternative is to stay on a Claude Code version or model where the regression is absent. The README's A/B baseline is v3.0.0 on v2.1.117, reporting a 95.5% cache hit rate through the proxy versus 82.3% direct on the first warm turn. That number is the project's own, from its release notes, and it is the kind of figure you should reproduce on your own transcripts rather than accept.
Licence, maintenance and what upgrading looks like
package.json declares MIT, and the repository carries a THIRD_PARTY_LICENSES file, which is what you would expect from a project that bundles or depends on other code. The GitHub repository metadata reports NOASSERTION for the licence, which conflicts with the MIT declaration in package.json. That is a discrepancy worth resolving with your own legal review before you depend on the package in a commercial setting; nothing here is legal advice.
The repository is not archived, and the last push was on 2026-09-05. Recent releases include v4.4.0-beta.0 (a first-exposure beta) on 2026-08-07, v4.3.0 (Remote Control through the proxy) on 2026-07-17, and v4.2.1 (an OAuth refresh scope hotfix) on 2026-06-23. The presence of a beta line alongside stable releases means you should pin a stable version rather than tracking latest.
Upgrade cost is mostly configuration drift. v4.0.0 flipped two defaults: thinking-block-sanitize v1 became on by default, and in-process extension hot-reload became opt-in behind CACHE_FIX_HOT_RELOAD=on. If you relied on hot-reload without setting that variable, an upgrade will change behaviour. A v4.2.1 hotfix for OAuth refresh scope suggests the opt-in OAuth path has had at least one correctness issue since it shipped.
The project accepts funding through a Buy Me a Coffee link in package.json. That is a maintenance signal in the weak sense only: it says the author is soliciting support, not that any particular cadence is guaranteed.
Editorial conclusion
Adopt claude-code-cache-fix only after you have measured your own transcripts and found a sustained low cache-read ratio or creation spikes on every --resume. Skip it if your long sessions already hold a high read ratio, if you rarely resume, or if you refuse to put a local process in the API path. Before installing, run the jq and awk pipeline from the README against a long session and record the read-ratio; after installing, confirm the proxy is listening on 127.0.0.1:9801 and that the same session's ratio moves.
Frequently asked questions
How does the Claude Code cache work, and what does claude-code-cache-fix change about it?
Claude Code records cache_read_input_tokens and cache_creation_input_tokens per request in its session transcripts, and the ratio between them determines what you pay. claude-code-cache-fix normalizes request structure, specifically block order, fingerprint and TTL, so the cache key stays stable and reads happen instead of repeated creations.
Can you delete the Claude cache, and does clearing it fix anything?
The README does not describe deleting a cache as a repair path. Its diagnostic reads existing session transcripts under ~/.claude/projects/ and computes a read ratio; the fix it offers is request normalization through the proxy, not cache deletion.
Does clearing the cache fix anything in claude-code-cache-fix?
The project does not present cache clearing as a solution. It targets unstable request prefixes that prevent cache reads, and it measures the problem using cache_read_input_tokens and cache_creation_input_tokens already written to your transcripts.
What is a cache in coding, in the context of claude-code-cache-fix?
Here it refers to Anthropic's prompt cache, which lets a repeated request prefix be read rather than re-created. The proxy's job is to keep that prefix stable so the read path is used; when it is not, the README describes repeated cache_creation_input_tokens spikes on resumed sessions.
Community notes