Urgent.News

What's breaking now, across thousands of outlets.

Tech

Prompt Caching: Why cache_control Writes But Never Reads

I turned on prompt caching for an agent loop that resends a 12K-token system prompt on every turn. Obvious win, right? Input tokens are the whole bill in a tool loop. The bill went up. Not a little. Roughly a quarter. And nothing in the logs looked wrong. Every request returned 200. Latency was the same. The only place the truth was written down was the usage object: cache_creation_input_tokens :…

The article discusses a common issue with prompt caching in AI agent loops. The author enabled prompt caching for a system prompt that is resent on every turn, expecting a performance boost. However, the caching mechanism only wrote to the cache and never read from it, resulting in a 40% increase in input tokens while still delivering the same result.

The key issue is that the cache_control breakpoint is placed after content that changes with each request, such as timestamps or user-specific information. This causes the cache to create a new entry for every request, resulting in no cached reads. The cache key is based on the rendered prompt up to each cache_control breakpoint, and any change at or after a breakpoint invalidates the cache entry.

The author explains that prompt caching works as a prefix match, where the cache key is the exact bytes of the rendered prompt up to the breakpoint. If a single byte changes at or after a breakpoint, the entire cache entry is invalidated. Therefore, if the cache_control breakpoint is placed after content that changes each request, the cache will always write a new entry and never read from the cache.

The article also highlights two silent killers that cause byte-identical payloads to still miss the cache: a 20-position lookback window in long tool turns and parallel fan-out, where an entry is only readable after the first response starts streaming. These issues can lead to the cache writing unnecessarily and never being read.

To ensure prompt caching is working correctly, the author suggests checking three fields in the usage object: input_tokens (uncached remainder), cache_creation_input_tokens (cost of writing to the cache), and cache_read_input_tokens (cost of reading from the cache). The sum of these fields should match the total prompt tokens used. If cache_read_input_tokens is consistently zero for repeated requests with identical prompts, something upstream is likely rewriting the prefix.

The article concludes with a top-level cache_control placement rule: it should be at the end of the shared portion of the prompt, not at the end of the whole prompt. This ensures that the breakpoint lands at the end of the fixed preamble followed by the unique per-request question, allowing the cache to effectively store and retrieve the unique parts of each request.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Limited development

I just made an whole IDE that can be on phone,I am 17 years old and with no budget or helpers,I coded since I was 7,I had every serious limitations such as low hardware,no support, unanvaliable tools…

What Changed When the Same Kata Needed a UI

The next question needed a visible result I began this exploration in From an Empty Repository to a Java Kata, One Module at a Time , following one Codex run from an almost empty repository to a Java…

Your app went viral. Adding servers made it worse. Here's why.

It's midnight, someone huge shares your app, 100,000 people show up — and the page dies. You add three servers. It gets worse .

  • 100,000 users caused app crash at midnight
  • Database bottlenecks revealed by request tracing
  • Indexing query and caching recommended to optimize

More from Saturday 12 September →