Skip to content

"Before the cache expires" still compacts on return once the cache has expired #28505

Closed as not planned

Description

@01-1

What happened

When compact idle threads set to "before the cache expires", it still compacts on return if cache is expired.

The user had Compact idle threads on "When you return" and switched it to "Before the cache expires (beta)" while a large Claude thread had been idle for hours. When she came back and sent a message, the composer ran /compact first. She expected this mode to replace compaction on return, not add to it, and switched to "Never" to stop it.

Diagnosis

"Before the cache expires" adds the background compaction on top of compaction on return. Only "Never" turns compaction on return off (v0.1.3):

  • apps/web/src/components/ChatView.tsx:2451: the Compact chip is offered whenever resolveIdleCompaction(...) !== "off".
  • apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts:9518: Claude's resume_return dialog is answered "continue" only for "off".
  • apps/server/src/orchestration-v2/IdleCompaction.ts:101: the background window returns null once the cache has expired.

So a thread that misses its background window compacts on return, on a cold cache. That is the cost this mode exists to avoid. The window can be missed because the cache was already cold when the mode was picked (this report), or because of #27915 or #28099.

The setting text ("after you return, just before its prompt cache expires, or never") and docs/user/providers-claude.md ("coming back does not reprocess the whole conversation") present the modes as alternatives. #23037 and #27915 suggest the fallback is intended, but nothing tells the user. The code is the same on v0.1.6 and main @ 5732bbe.

Suggestion: split this mode into two options:

  • Before the cache expires (fall back to when you return): today's behavior.
  • Before the cache expires (no fallback on return): a thread that missed its window sends with the full history.

At minimum, the setting text and docs should say the current mode falls back.

Steps to reproduce

  1. Set Compact idle threads to "When you return".
  2. Work in a Claude thread until it holds more than 200K tokens. Leave it idle past its prompt cache TTL (1h here).
  3. Set Compact idle threads to "Before the cache expires (beta)".
  4. Return to the thread and send a message.

Expected: the message sends with the full history, since the warm-cache window has passed. Or the setting says it falls back to compacting on return.
Actual: the composer runs /compact (idleCompaction: "onReturn") before the message, on the cold cache.

Version

0.1.3 (desktop app; server reports serverVersion 0.1.3). Same code on v0.1.6 and main @ 5732bbe.

Environment

Fedora Linux 44 x64 (kernel 7.2.11), desktop app (AppImage) with its local server, Claude Code 2.1.316, claude-opus-5-5, 1h prompt cache TTL

Evidence

# Affected thread: statev2.sqlite projections, server.trace.ndjson. Times are 2026-11-01 UTC.
last usage before return: usedTokens=385096 promptCacheTtlMs=3600000 promptCacheExpiresAt=2026-10-31T13:07:23Z

03:15:30Z server.updateSettings (mode change; value not traced)
03:16:10Z run 16 /compact idleCompaction=onReturn failed
03:17:38Z run 18 /compact idleCompaction=onReturn interrupted
03:17:44Z Wait for context compaction to finish before steering the thread.
03:17:58Z run 20 /compact idleCompaction=onReturn interrupted
03:18:26Z server.updateSettings (value not traced)
03:18:49Z run 24 /compact idleCompaction=onReturn interrupted
03:19:43Z run 26 /compact idleCompaction=onReturn interrupted
03:20:20Z server.updateSettings (settings.json now idleCompaction: "off")

# The user interrupted each compaction, so each next send got another /compact.

Related issues

#27915 and #28099 cover the skipped background compaction and treat the fallback as expected. #26799 is about "Never" compacting. #19182 asked for compaction while the cache is warm or not at all. None covers this case.

Fix applied or workaround

None applied; nothing was changed on the machine. Options: "Never" (also loses the background compaction), or set the composer's Compact chip to "Full" before each stale send.

Filed by

Claude Code (claude-opus-5-5) via t3 triage

Activity

  1. juliusmarminge commented on Nov 12, 2026

    @juliusmarminge
    Member

    Thanks for writing this up. It asks for new behaviour rather than reporting a defect, so it does not belong in the bug tracker and I'm closing it as not planned here. Feature ideas are discussed in Discussions: please post it there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions