[BUG] Parallel API during user turn cause significant prompt cache write penalty on Bedrock
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong
Claude Code fires 2–7 parallel API calls per user turn — not just at session startup. All calls receive identical inputs and independently write the prompt cache. This means every cache miss (TTL expiry, session start) incurs N× the necessary write cost instead of 1×.
Discovered by analyzing session JSONL transcripts at millisecond resolution. The signature is groups of JSONL entries with identical cache_creation_input_tokens and cache_read_input_tokens values, but timestamps 750ms–4s apart, each returning a different content block type (text, thinking, tool_use).
Evidence
Turn 1 of a session (v2.1.81, Bedrock Sonnet 4.6):
20:01:05.953Z write=10,553 read=0 output=10 ['text']
20:01:06.715Z write=10,553 read=0 output=10 ['thinking']
20:01:07.515Z write=10,553 read=0 output=117 ['tool_use']
Three separate API calls, 750ms apart, identical inputs, each independently writing 10,553 tokens.
If these were sequential (each processing the previous call's output), the second and third calls would have larger inputs — they don't. If they were streaming events from one call, they'd be milliseconds apart — they aren't.
Turn 2 of the same session (warm-cache GOOD turn):
20:01:31.878Z write=8,905 read=16,989 output=1 ['text']
20:01:35.486Z write=8,905 read=16,989 output=408 ['tool_use']
Both calls independently write 8,905 delta tokens. One should write; the other should read.
TTL recovery event (one of 5 in the session):
14:37:40.xxx Z write=124,192 read=0 output=0 ['thinking']
14:37:40.xxx Z write=124,192 read=0 output=0 ['text']
14:37:46.000Z write=124,192 read=0 output=0 ['tool_use']
14:37:52.000Z write=124,192 read=0 output=882 ['tool_use']
4 parallel calls × 124,192 tokens = ~$3.10 in cache writes for what should cost ~$0.78 (1 write + 3 reads).
Distribution in one 304-entry session
Turns with 1 API call: 84
Turns with 2 API calls: 55
Turns with 3 API calls: 26
Turns with 4 API calls: 5
Turns with 5 API calls: 1
Turns with 7 API calls: 1
Every multi-call group has identical cache_creation_input_tokens and cache_read_input_tokens across all calls — confirming they share the same input state.
Cost Impact
For this session (304 JSONL entries, ~170 actual turns):
- Measured input cost: $18.45
- Estimated ideal (1 call/turn): ~$9
The multiplier is worst during TTL recovery: each expiry at large context size triggers N simultaneous full-context writes instead of 1.
Why This Differs from the Known Parallel Startup Writes
The 3–4 parallel startup write behavior is documented and accepted. What's described here is that the same pattern repeats at every turn — not only at session init. Mid-session turns with warm cache also fire 2–3 parallel calls, each independently writing delta tokens. The cost impact is smaller per-turn for warm turns but accumulates significantly over a long session, and is catastrophic on TTL recovery events.
Claude Code Version
2.1.81
Is this a regression?
Unknown — this may be intentional (speculative execution for latency), but it has significant cost consequences on Bedrock that weren't present or noticeable before longer/heavier sessions became common.
Platform
AWS Bedrock
Operating System
macOS Darwin 25.3.0
Terminal/Shell
zsh
Related Issues
- #34629 — prompt cache regression in
--print --resume - #37188 — cache_control TTL ordering with concurrent agents (Bedrock)
- #36243 — 1h TTL not propagated to subagent requests on Bedrock
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗