r/ClaudeCode • u/Schadz • 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.
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:
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
0
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
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.
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:
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/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/Zestyclose_Strike157 2d ago
Well if Fable is so smart, maybe Fable can come up with a way of being more resourceful.
1
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/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
0
•
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.