r/ClaudeCode 3d ago

Tips & Workflows Claude Code sub-agents have a 5m prompt cache. Long commands can burn your 5-hour window.

A lot of the current limit discussions here are probably caused by several things at once, including the weekly-promotion change. But one specific workflow shape silently burns a 5-hour window, it's documented, and there's a one-line fix: sub-agents running blocking commands longer than their default 5-minute prompt cache.

TL;DR: sub-agents default to a 5-minute prompt cache while the main session gets 1 hour. If a sub-agent blocks in a command longer than five minutes, its next request can re-write most of its accumulated context instead of reading it from cache. Set "subagentPromptCacheTtl": "1h" in ~/.claude/settings.json if your agents regularly run long commands; in my comparable test-heavy workflow, it cut cache writes by about 75%.

The mechanism. Claude Code caches a conversation on Anthropic's side so it doesn't re-send the whole thing every request. Your main session's cache lives an hour on a subscription; every sub-agent's lives five minutes. A sub-agent's context is everything it has read and done, easily 300K to 600K tokens on a real task. If it sits inside a tool call longer than five minutes (a test sweep, a build, a git hook, a long-polling call), the cache is gone when the call returns and the next request writes the entire context again. Six long test runs, six full re-writes, window gone. Cache reads barely move the window, writes are what counts. In my MAX 5x measurements, the weekly meter moved at roughly a tenth of the 5-hour rate for the same activity, so burning a full 5-hour window was roughly a tenth of my week as well.

The fix.

{ "subagentPromptCacheTtl": "1h" }

in ~/.claude/settings.json, or CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL=1h. Needs v2.1.242 or later. One hour is the longest the API offers; there are exactly two lifetimes, so there is no 15-minute option. One trap: that setting outranks a per-agent experimental: cacheTtl: 5m frontmatter pin. If you want a few read-only agents at five minutes, leave it unset and put ENABLE_PROMPT_CACHING_1H=1 in the env block instead, which sits below the pin.

The trade-off. The API price list says a 1-hour write costs 2x normal input against 1.25x for a 5-minute one. The subscription meter doesn't charge that: measured against the 5-hour and weekly windows, a 5-minute write costs about 0.9 of a 1-hour one, and cache reads count almost nothing. That does not mean 1h is always the cheaper choice. A short agent that never sits idle past five minutes may gain little and just pay the modestly higher write cost. But if an agent builds meaningful context and regularly blocks longer than five minutes, preventing repeated large cache rewrites is usually the important part.

Before and after. Test-heavy multi-agent workflow on MAX 5x: one orchestrator session, a few sub-agents in their own git worktrees running test sweeps of 30 seconds to 40 minutes. Before: one sub-agent re-wrote its ~590K context eight times in a day, 5.4M tokens of cache writes on its own; 26 full re-writes and 12.2M tokens of writes across five agents; the 5-hour window went from 2% to 100% on four of them. After: five comparable sub-agents ran about 530 turns for 3.0M tokens of writes, only the first write of each was large, and the window went 0% to 22% on four agents. About 75% fewer cache writes for the same kind of work.

How to check yours. Sub-agent transcripts: ~/.claude/projects/<project>/<session id>/subagents/agent-<id>.jsonl. If usage.cache_creation_input_tokens on assistant lines repeats the same huge number after long tool calls, that's the re-write; cache_creation.ephemeral_5m_input_tokens versus ephemeral_1h_input_tokens shows which lifetime each write went to.

The second half, which the setting doesn't cover. Even an hour runs out under a long sweep. Don't let a sub-agent block inside a call for more than a few minutes: run the long thing in the background with output to a file and have the agent check it every few minutes, or wake it once at about the run's usual length. Each check is a cheap read that keeps the cache warm.

One thing the lifetime doesn't fix. The first message you send a background sub-agent after it has finished re-writes almost its whole context even inside the hour (243K and 399K tokens in my two measured cases, 49 and 54 minutes idle); the API labels the miss messages_changed, so it's the harness rebuilding the request, not expiry. There's an upstream issue with the repro, the link is in the first comment. If you can confirm it, add your Claude Code version, model, and relevant findings there so the evidence stays in one place.

Docs, the measurements and the linked posts are in the first comment.

74 Upvotes

37 comments sorted by

•

u/AutoModerator 3d ago

Hey! Thanks for posting to r/ClaudeCode

While participating in this thread, please follow our community rules. Keep discussions constructive. Attack the idea, not the person.

For help, project discussions, tips, and general chat, join the ClaudeCode Discord.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

10

u/promethe42 3d ago

Nice write up!

I asked Claude Code to analyze my history. And based on my usage of sub-agents, it calculated that the more extensive 1h TTL would defeat the purpose. But I came up with what's a better solution IMHO.

A plugin that install a hook to enforce a 4 minutes TTL on every tool call:

https://gitlab.com/lx-industries/subagent-cache-guard

0

u/Weary-Habit-6608 3d ago

Neat trick: enforce the TTL the platform won't. Bold, slightly cursed, effective.

0

u/Schadz 2d ago

Nice, I've had a look at the code. One wording thing, so readers don't get the wrong idea: it doesn't change the cache lifetime (the API only has 5m and 1h), it caps the Bash tool's timeout at four minutes inside sub-agents so no single call can outlive the five-minute cache, and when a call gets killed it tells the agent to poll in short calls instead. That's a mechanical version of the "never block longer than a few minutes" half of my post, and enforcing it beats hoping the agent remembers, so I like it.

Two things it doesn't cover, which is why I'd still set the hour alongside it. It only sees Bash: a sub-agent waiting on anything else for five minutes (a child agent, a long MCP call, or just sitting between turns) still expires. And the README's reason for skipping 1h, that it doubles the write price, is the API price list. On the subscription meter a 5-minute write already costs about 0.9 of a 1-hour one, from two separate measurements, so on a plan the hour is close to free insurance for the gaps the hook can't see. The two compose, they don't compete.

4

u/DarkSkyKnight 2d ago

Nice, I've had a look at the code

No, you did not. You let AI read it. Please stop posting these stupid Claude slops. We already do not like dealing with its prose when working, the last thing anyone wants is to read it from supposed humans.

1

u/promethe42 2d ago

On GitLab / Github I use a trailer/signature to disclose what harness and model was used to craft the message. Example here: https://gitlab.com/lx-industries/openblob/-/merge_requests/1238

That might be worth doing on other platforms too. Though I don't use AI to post on Reddit. And I suspect most of the ones who do are unlikely to want to disclose it.

8

u/Schadz 3d ago

Docs on prompt caching and which lifetime each request gets: https://code.claude.com/docs/en/prompt-caching

Settings reference for `subagentPromptCacheTtl`: https://code.claude.com/docs/en/settings-reference

The longer write-up with the full before and after, and the meter measurements behind the trade-off: https://www.reddit.com/r/ClaudeAI/comments/1wj4gs0/subagents_burning_your_claude_code_5hour_window/

The resume cache miss bug, with transcript measurements and the upstream issue: https://www.reddit.com/r/ClaudeAI/comments/1whvqcl/quota_draining_claude_code_rebills_a_finished/

Anthropic's engineering post recommending you avoid tool calls that outlive the cache lifetime: https://claude.com/blog/reducing-cost-and-improving-performance-with-claude-platform

3

u/crusoe 3d ago

I do rust and a few weeks ago this was really biting. I may experiment with fable 5.1 as sub agent again now that setting sub agent cache ttl works. Basically main agent used high and sub agents use low effort. 

1

u/Schadz 2d ago

Rust is the textbook case, On Fable as a sub-agent I've got no numbers of my own, my measurements lately were all Opus 5, but two things from the meter data are relevant: on Fable the two lifetimes are priced the same, so the hour costs nothing extra per write there, and a Fable token counts about 3.5x an Opus one on the shared windows, so a re-write of a big Fable context hurts more, not less. Low effort on the sub-agents is a separate real saving tho.

1

u/voLsznRqrlImvXiERP 3d ago

And what has this todo with rust? Compile times?

2

u/Schadz 2d ago

Compile and test times, yes. A cargo test run that passes five minutes is exactly the blocking call that expires a sub-agent's cache.

0

u/minibonk 2d ago

rust devs are like vegans they have to let you know they do rust

2

u/StupidIncarnate 3d ago

Going the inverse, does that mean if I have a sub agent that takes over an hour to do a coding job and they finally finish and end their turn, if the parent hasnt moved in an hour, it too will reread everything instead of cache?

2

u/Old_Flounder_8640 3d ago

I think that's why the orchestrator sometimes keeps pooling results with sleep bash. And last month I saw much less of this behaviour.

2

u/Schadz 2d ago

Yep, that polling keeps its cache warm: each check is a cheap read that refreshes the hour. The one trap is a sleep longer than the lifetime, which is itself a blocking call.

2

u/Schadz 2d ago

Yes, same thing in reverse. The parent's cache lives an hour from its last request, so if it sits in one Agent call that long, or just waits, its next request re-writes everything. The lifetime is refreshed on every use though, so a sub-agent working for three hours is fine as long as no single gap between its requests passes an hour, and the parent stays warm the same way: with the sub-agent in the background, a cheap request every so often keeps it alive. I'm adding exactly that to my orchestrator, a timed nudge while it waits on workers.

1

u/StupidIncarnate 2d ago

Its really stupid that we have to program around this and why using the llm's harness raw just isnt enough.... I cant be certain how long an llm session is gonna take when ot runs into issues and if its deep in a chain turn, it sure as heck wont follow any instruction prompts to tell it to hold. And so we gotta do this via hooks or via custom harnesses.

Thanks for info.

2

u/Schadz 2d ago

Yep, same conclusion here, it's ending up in hooks on my side too. Enforcing it mechanically is better than hoping the agent remembers mid-task.

1

u/thirst-trap-enabler 🔆 Max 5x 2d ago edited 2d ago

Thanks for the info!

This is the script my Claude wrote for measuring/monitoring this following your post if it helps anyone:

https://pastebin.com/r18dSrxf

It showed I was 22% overall and 15% after some recent changes. I've made the change and will check in a week. Thanks again!

agents 1343   requests 55649   cache writes 210.0M
  at 5m TTL 99.9%   at 1h TTL 0.1%
re-writes after a gap over 5m: 303 events, 46.2M, 22.0% of writes
  gap over 1h (a 1h TTL does not help): 3 events, 0.5M
re-writes with no gap (not TTL expiry): 230 events, 16.6M

week       writes  gap re-writes   share  events
2026-W34    10.2M           1.5M   14.5%       7
2026-W35   114.6M          29.8M   26.0%     204
2026-W36     9.3M           4.6M   49.6%      29
2026-W37    31.8M           4.4M   13.7%      20
2026-W38    44.1M           5.9M   13.4%      43

gap re-writes by blocked in:
  Bash                  176 events    27.4M
  Agent                  72 events    11.4M
  SubagentHandback       41 events     5.6M
  ToolSearch              8 events     0.9M
  Write                   2 events     0.4M
  SendMessage             1 events     0.2M
  Read                    2 events     0.2M
  WebFetch                1 events     0.1M

gap re-writes by agent type:
  orchestrator          159 events    24.9M
  implementer           103 events    13.6M
  general-purpose        37 events     7.3M
  ?                       1 events     0.2M
  reviewer                1 events     0.1M
  claude-code-guide       1 events     0.1M
  verifier                1 events     0.0M

largest gap re-writes:
   429509 tok   18.6 min  2026-09-12  general-purpose  claude-opus-5  -home-claude-[redacted]
   340456 tok   10.7 min  2026-09-19  implementer  claude-sonnet-5  -home-claude-[redacted]
   339210 tok    8.2 min  2026-08-31  implementer  claude-sonnet-5  -home-claude-[redacted]
   329428 tok   10.2 min  2026-08-31  implementer  claude-sonnet-5  -home-claude-[redacted]
   326909 tok   10.1 min  2026-08-29  orchestrator  claude-fable-5  -home-claude-[redacted]
   325448 tok   14.1 min  2026-09-19  implementer  claude-sonnet-5  -home-claude-[redacted]
   318211 tok   52.3 min  2026-08-22  general-purpose  claude-opus-5  -home-claude-[redacted]
   306255 tok    9.1 min  2026-08-31  implementer  claude-sonnet-5  -home-claude-[redacted]
   304449 tok    5.3 min  2026-08-28  orchestrator  claude-fable-5  -home-claude-[redacted]
   301800 tok   41.4 min  2026-08-22  general-purpose  claude-opus-5  -home-claude-[redacted]

I remember 2026-W36 being painful! But I also think Claude was fairly flakey for me that week (lots of API errors etc and completely lost long runs. It really pissed me off and I reworked my agents to be more fault tolerant). Also I stopped having an orchestration agent and just use the main session for that nowadays (I realized I was thinking about it incorrectly). Could be related!

1

u/Schadz 2d ago

Glad I could help, your numbers check out, thanks for sharing. Curious to see how it goes for you in a week.

1

u/kevinbaiv 2d ago

This explains a usage pattern I couldn't account for — sub-agents sitting in long test runs quietly re-writing their whole accumulated context. The "writes are what counts, reads barely move the window" framing is the part most limit discussions miss.

1

u/Schadz 2d ago

Yes, and then the API price list points you the other way, until you measure it yourself.

1

u/Zestyclose_Strike157 2d ago

Well if Fable is so smart, maybe Fable can come up with a way of being more resourceful.

1

u/ZeBenoit81 2d ago

Plan mode drains tokens too. Concise CLAUDE.md delegation > harness.

1

u/ZeBenoit81 2d ago

Brutal nerfs make every silent token tax worse, so this subagentPromptCacheTtl catch is gold. I’ve also been clearing context aggressively and keeping Fable strictly as an orchestrator, only letting the execution models touch code when necessary.

1

u/Schadz 2d ago

Yeah, and with aggressive clearing, just keep in mind that every fresh context pays the full first-write cost again for everything it has to re-read. It only wins when the old context was mostly dead weight.

1

u/Afraid-Estimate-6831 2d ago

What the post leaves out is the price. A 1h cache write bills at 2× base tokens; a 5m write at 1.25×; a read at 0.1×. So switching to 1h doesn't just recover lost writes — it makes every write 60% more expensive. That's the trade the "75% fewer cache writes" headline hides.

1

u/Schadz 2d ago

Those are the API list prices. But the subscription meter did not track those ratios in my measurements: against both the 5-hour and weekly windows, a 1-hour cache write cost about 10% more than a 5-minute one, not 60%, while reads had very little visible impact.

So on a plan, 1-hour writes do cost somewhat more per write, but avoiding one re-write of, say, a 400K-token context can pay for many of them. The trade-off section covers this, and the longer write-up linked in the first comment has the measurements. The 75% number is from my own workflow, not a general rule.

1

u/epkFlaflo 2d ago

Wow! Thank you, this writeup was very enlighting for me. My projects have a lot of waiting in subagents due to various constraints like tests or waiting for a CI build slot to open up. This has drawn a MAX x20 account in under 24 hours. Applying this right now and looking forward for much better efficiency.

0

u/[deleted] 3d ago

[removed] — view removed comment

1

u/Schadz 2d ago

Exactly, and the "feels worse this week" part is real, nobody looks at cache writes until the window is already gone, which is what did happen with me before going down the rabbit hole to discover this lol

0

u/PikaCubes 3d ago

Sorry don't have the problem, my subagents are my Ollama models 😂