Repository navigation
Description
Summary
When compaction runs against an Anthropic model, every request writes a prompt cache entry that is never read back. Over 7 days on this machine, 70 successful compactions wrote 1,278,055 cache tokens and read exactly 0.
Cache writes are billed at a premium over ordinary input tokens, so this is a pure surcharge on every compaction with no possibility of payback. The compaction payload is unique by construction, because the window that selects the conversation slice slides forward each time, so no prefix is ever shared between two compaction requests.
Measurement
Read from ~/.local/share/opencode/opencode.db, 7-day window, provider anthropic, model claude-haiku-4-5 configured as agent.compaction.model.
| Class | Count | tokens.total |
cache.write |
cache.read |
|---|---|---|---|---|
| summary produced | 70 | present | 1,278,055 total | 0 in all 70 |
| summary empty | 15 | key absent | 0 | 0 |
Representative rows from the successful group, showing that essentially the whole prompt goes to a cache write while billed input stays at 3 tokens:
3780 chars {"total": 8995, "input": 3, "output": 1486, "cache": {"write": 7506, "read": 0}}
7675 chars {"total": 14596, "input": 3, "output": 3049, "cache": {"write": 11544, "read": 0}}
7637 chars {"total": 19457, "input": 3, "output": 2985, "cache": {"write": 16469, "read": 0}}
7586 chars {"total": 19631, "input": 3, "output": 2971, "cache": {"write": 16657, "read": 0}}
8894 chars {"total": 27165, "input": 3, "output": 3533, "cache": {"write": 23629, "read": 0}}
cache.read is 0 in every one of the 70, not merely low on average.
Reproduction
Configure an Anthropic model as the compaction model, run sessions long enough to compact several times, then query the database:
import sqlite3, json, time
from pathlib import Path
db = Path.home() / ".local/share/opencode/opencode.db"
c = sqlite3.connect(f"file:{db}?mode=ro", uri=True)
since = int((time.time() - 7 * 86400) * 1000)
reads = writes = 0
for mid, _, data in c.execute(
"select id,time_created,data from message where time_created>?", (since,)
):
r = json.loads(data)
if not (r.get("summary") is True and r.get("mode") == "compaction"):
continue
if r.get("providerID") != "anthropic":
continue
cache = (r.get("tokens") or {}).get("cache") or {}
reads += cache.get("read", 0)
writes += cache.get("write", 0)
print("cache read:", reads, " cache write:", writes)Expected
Compaction requests should not request prompt caching, or the cache scope for them should be configurable. The summarization system prompt is small and stable and could reasonably stay cached; the conversation payload is what carries the volume and it is never reused.
Notes on cause
I did not trace this in source, so treat this part as a hypothesis rather than a finding. Reading the shipped bundle, the Anthropic request builder appears to attach cache_control: {type: "ephemeral"} to the system prompt and to the last two messages without a condition that would exclude compaction requests. The measurement above stands on its own regardless of where the marker is attached.
I also could not find any user-facing setting that would turn this off. The top-level config keys in the shipped build are logLevel, server, command, reference, snapshot, plugin, autoshare, disabled_providers, enabled_providers, small_model, mode, agent, provider, permission, tools, attachment and layout, none of which covers caching. There is an internal structure shaped like {tools, system, messages, ttlSeconds} that looks purpose-built for this, but I found nothing wiring it to user configuration.
Environment
- opencode-ai 1.18.30, Linux x64
- Compaction model:
anthropic/claude-haiku-4-5, set viaagent.compaction.model
Activity
github-actions commentedon Sep 11, 2026
This issue might be a duplicate of an existing issue. Please check:
opencodejr commentedon Oct 28, 2026
Thanks for the careful measurement and the reproduction script, it makes the problem very clear.
This report is about OpenCode v1 (
opencode-ai1.18.30). v1 now only gets fixes for critical bugs such as data loss, security problems or crashes with no workaround. The extra cache-write cost on compaction requests doesn't fall into that group, so it's unlikely to be fixed in v1.We'd encourage you to try v2 (the
@opencode/clipackage,opencodecommand), where active work on the prompt cache and compaction is happening. Related v2 issues:If you see the same 0-read / all-write pattern for compaction on v2, or you think this is critical for v1, please reply here with the details.
opencodejr commentedon Oct 29, 2026
We haven't heard back, so I'm closing this as not planned. The report is about OpenCode v1 (
opencode-ai1.18.30). v1 only gets fixes for critical bugs, and the extra cache-write cost on compaction requests isn't one of them.Thanks again for the detailed measurements. Prompt cache and compaction work is happening in v2 (see #52761, #54107, #53927 and #51109). If compaction requests on v2 also write cache entries that are never read, please open a new issue with your v2 version and the same numbers.