Developers found that Claude’s prompt-caching can fail silently, charging premium rates while returning zero cached tokens. A week-long log run on a WhatsApp handler showed no cache reads at all, yet the API billed for the caching feature—dropping costs from $1,890 to $406 per month.
Why the issue matters
Prompt caching is meant to cut costs and speed up responses by reusing a static portion of a prompt (the “prefix”). When it works, high-traffic apps can shave hundreds of dollars off their monthly bills. When it doesn’t, developers pay for a feature they never actually use, and the silent failure gives no error or warning to hint at the problem.
How the bug shows up
The API accepts a cache-control flag and a prefix, then reports how many tokens were read from the cache. In the observed case, every request returned a cache-read count of zero. The call succeeded, no exception was thrown, and the billing reflected the premium cache cost. The failure is invisible unless you explicitly log the read count.
Common ways the cache gets broken
- Prefix is too short – Each Claude model defines a minimum token length for a cacheable prefix. Haiku 4.5 needs at least 4,096 tokens; Sonnet 4.6 needs only 1,024. Sending a shorter prefix satisfies the request format but the service ignores the cache instruction.
- A volatile byte moves – Caching requires an exact byte-for-byte match. Adding a dynamic element such as a timestamp,
new Date(), or a user email to the front of the system prompt changes the byte sequence, causing every request to be treated as a fresh, uncached write. - Tool list order changes – Tools are prepended to the prompt. If the tool array is built from object keys, the iteration order can vary between calls, shifting the byte layout and breaking the cache.
Fixes you can apply today
- Validate prefix length – Before sending a request, estimate the token count of the prefix against the model’s minimum. Reject or pad the prefix if it falls short.
- Log cache reads on every call – Record the “cache read tokens” field. A streak of zeros is a clear sign the cache is not being hit.
- Freeze the prompt’s leading bytes – Keep dynamic data out of the cached segment. If you must include user-specific information, place it after the cached prefix.
- Synchronize model identifiers – Ensure the model ID used in routing matches the one stored in your cache table; mismatched IDs prevent a cache lookup.
The cost angle
For an app that makes thousands of calls daily, moving from uncached to cached can drop monthly expenses dramatically—from roughly $1,890 to $406 in the reported case. Even modest traffic sees noticeable savings, and the performance boost of reusing a large static prompt can reduce latency.
Counterpoint
However, the silent nature of the failure means the only way to be sure you’re not overpaying is to check the read count—something many overlook.
What to watch next
- Metric dashboards – Add a gauge for cache-read tokens alongside request volume.
- Tool-ordering stability – If you rely on dynamically generated tool lists, consider sorting them deterministically before embedding them in the prompt.
Bottom line: Claude’s prompt caching does not raise an error when it silently ignores your request. Verify cache effectiveness by logging read tokens, enforce a proper prefix length, and keep the leading bytes of the prompt immutable. Only then will you reap the promised cost and speed benefits.
