anomalyco / anomalyco/opencode
Production evidence: Anthropic cache bust bug causes $14.82 waste across 3 sessions (22.5% bust rate)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
Production data from OpenCode 1.18.9 shows the Anthropic prompt cache bust bug (Issue #24841) is still active and causing significant financial waste.
Key findings:
- 5 sessions using Opus 5 max cost $38.35
- $24.45 (63.8%) of that was cache write charges
- 9 cache busts in a single 43-message session (22.5% bust rate)
- 5 consecutive cache busts in a row (messages #34-38), each costing $1.63
- All 9 cache busts occurred immediately after tool-calls, confirming the root cause identified in #24841
Estimated waste: $14.82 (39% of total cost) could have been avoided if caching worked correctly.
Evidence
Session 1: ses_03563ecbdffe92x5KFrsYJRWnN ($18.66)
Title: Creating AGENTS.md for repository
Date: 2026-08-04
Messages: 43 (38 tool-calls, 2 stop)
Total tokens: 80 input / 48,028 output / 6,148,780 cache read / 2,301,161 cache write
Cost breakdown:
| Component | Tokens | Rate | Cost | % |
|---|---|---|---|---|
| Input | 80 | $5.00/M | $0.00 | 0% |
| Output | 48,028 | $25.00/M | $1.20 | 6.4% |
| Cache Read | 6,148,780 | $0.50/M | $3.07 | 16.5% |
| Cache Write | 2,301,161 | $6.25/M | $14.38 | 77.1% |
Cache bust pattern (all after tool-calls):
msg# cache_read cache_write cost prev_finish flag
1 0 84,195 $0.55 (start) CACHE RESET
21 0 233,523 $1.47 tool-calls CACHE RESET
29 0 255,794 $1.61 tool-calls CACHE RESET
30 0 256,289 $1.61 tool-calls CACHE RESET
34 0 259,313 $1.63 tool-calls CACHE RESET
35 0 259,498 $1.63 tool-calls CACHE RESET
36 0 259,734 $1.63 tool-calls CACHE RESET
37 0 260,018 $1.63 tool-calls CACHE RESET
38 0 260,207 $1.63 tool-calls CACHE RESET
Consecutive cache busts (#34-38): 5 in a row, wasting $8.15
Expected cost if cache worked: $5.84
Actual cost: $18.66
Waste: $12.82 (69%)
Session 2: ses_03861eca0ffeuobD3dLHqYq99p ($11.50)
Title: LLM速度对比与Agent配置优化建议
Date: 2026-08-03
Messages: 73 (67 tool-calls, 3 stop)
Cache busts: 2
Cache write: 523,712 tokens × $6.25/M = $3.27 (28.5% of cost)
Session 3: ses_0381fd091ffe4KS4TxsnTcsOFW ($7.51)
Title: Claude Code Max订阅与API token费用对比
Date: 2026-08-03
Messages: 45 (35 tool-calls, 5 stop)
Cache busts: 2
Cache write: 498,810 tokens × $6.25/M = $3.12 (41.5% of cost)
Comparison: DeepSeek V4 Pro (no cache write fee)
Session: ses_02b3612c6ffeOFnJw6eQrlTKW0 (2026-08-06)
Cost: $0.03
Cache write: 0 (DeepSeek does not charge for cache writes)
Cache read: grows steadily from 2K to 89K (no busts)
This demonstrates that the issue is specific to Anthropic's cache write pricing combined with the cache bust bug.
Root Cause
Matches Issue #24841 exactly:
- OpenCode's prompt loop reloads all messages from DB via
filterCompactedEffect()at the start of every iteration - Tool parts transition from
pending→completedwith output text between API calls toModelMessages()serializes the conversation with different bytes- Anthropic's prompt cache sees different content → cache invalidated from that position forward
- Entire conversation context (~250K tokens) re-written at cache-write pricing ($6.25/M)
Verified: All 9 cache busts in the $18.66 session occurred immediately after tool-calls finish type.
New Evidence Not in Previous Reports
-
Consecutive cache busts: 5 in a row (messages #34-38), each costing $1.63. This suggests the cache is being invalidated on every single turn during heavy tool-use loops.
-
Cache bust rate: 22.5% (9/40 messages) in a real production session with only 43 messages.
-
Cost per bust: $1.46-$1.63 (250K tokens), lower than the $3.50 (560K) reported in #24841, but still significant at scale.
-
Production cost data: Real money wasted ($14.82 across 3 sessions) with exact per-message cost breakdown from OpenCode's SQLite database.
Database Queries
Query 1: Session-level cache stats
SELECT
id,
cost,
tokens_input,
tokens_output,
tokens_cache_read,
tokens_cache_write
FROM session
WHERE id = 'ses_03563ecbdffe92x5KFrsYJRWnN';
Query 2: Message-level cache pattern
SELECT
json_extract(data, '$.finish') as finish,
json_extract(data, '$.tokens.cache.read') as cache_r,
json_extract(data, '$.tokens.cache.write') as cache_w,
json_extract(data, '$.cost') as cost
FROM message
WHERE session_id = 'ses_03563ecbdffe92x5KFrsYJRWnN'
AND json_extract(data, '$.role') = 'assistant'
ORDER BY json_extract(data, '$.time.created');
Query 3: Verify cache busts after tool-calls
WITH msg_list AS (
SELECT
json_extract(data, '$.finish') as finish,
json_extract(data, '$.tokens.cache.read') as cache_r,
json_extract(data, '$.tokens.cache.write') as cache_w,
ROW_NUMBER() OVER (ORDER BY json_extract(data, '$.time.created')) as rn
FROM message
WHERE session_id = 'ses_03563ecbdffe92x5KFrsYJRWnN'
AND json_extract(data, '$.role') = 'assistant'
)
SELECT
m1.rn,
m1.cache_r,
m1.cache_w,
m2.finish as prev_finish
FROM msg_list m1
LEFT JOIN msg_list m2 ON m1.rn = m2.rn + 1
WHERE m1.cache_r = 0 AND m1.cache_w > 0;
Impact
- Financial: $14.82 wasted across 3 sessions (39% of total Opus 5 spend)
- User trust: Users expect prompt caching to work as advertised; silent cache busts at 12.5x read cost are unacceptable
- Model choice: Forces users to avoid Anthropic models on Zen for tool-heavy workloads, limiting model selection
Request
- Reopen Issue #24841 or create a new issue with this evidence
- Prioritize PR #36852 (or equivalent fix) to cache messages across prompt loop iterations
- Add cache bust detection/logging so users can see when this is happening
- Consider a cost warning when cache bust rate exceeds a threshold
Environment
- OpenCode: 1.18.9
- OS: macOS (darwin)
- Provider: OpenCode Zen (
opencode/claude-opus-5) - Variant: max
- Agent: Sisyphus - ultraworker (via oh-my-openagent)
Additional Data
Full session data available upon request (can export from ~/.local/share/opencode/opencode.db). Per-message cost breakdown available. Can provide additional sessions if needed.
Related: #24841 #25366 #31525 #20110 #36852
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with Issue #24841 and PR #36852, then trace the prompt loop through filterCompactedEffect() and toModelMessages(). Use the provided SQLite queries against the referenced session to confirm cache resets after tool calls; done means cache reuse persists across iterations and the reported bust pattern no longer occurs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- ai, backend, databases, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100