Skip to content

Compaction budget too small for large-context models #51711

Closed as not planned
Closed as not planned

Description

@naoufalelbani

Description

usable() in packages/opencode/src/session/overflow.ts subtracts a model's full capped
output limit from the context window instead of a bounded reservation.

With context=1048576 and output=524288 plus a large
OPENCODE_EXPERIMENTAL_OUTPUT_TOKEN_MAX, the budget becomes
1048576 - 524288 = 524288, so the session compacts at 600k with roughly 500k of window
still free.

Three related problems in the same area:

  • the input branch ignores context, so context=100k, input=500k yields a 480k budget that exceeds the real window
  • token accounting omits reasoning
  • processor.ts calls isOverflow without flags.outputTokenMax, unlike compaction.ts, so pre- and post-request thresholds can differ

Worth noting for triage: a reading near 16.6k after compaction is just the ~15k retained
tail plus the summary, not a 16k context limit. Easy to misread as a broken threshold.

Plugins

None

OpenCode version

dev (branch compaction-budget off dev)

Activity

  1. github-actions commented on Sep 27, 2026

    @github-actions
    Contributor

    This issue might overlap with existing issues. Please check:

    • #29363: discusses usable() subtracting maxOutputTokens from context when limit.input is absent, causing incorrect compaction/overflow budgets with large output limits.
    • #38835: reports the no-limit.input branch in usable() ignoring the configured compaction.reserved value.

    The reasoning-token accounting and outputTokenMax consistency points may be additional distinct findings.

  2. liudongyan13701205717-source commented on Oct 1, 2026

    @liudongyan13701205717-source

    Desktop-app data point — compaction frequency, plus a repro-scale measurement

    Adding an environment the existing reports don't cover: Windows 11 + the opencode desktop (Electron) app (@opencode-aidesktop, plugin SDK @opencode-ai/plugin@^1.18.32), provider opencode, model big-pickle. Everything I found here was read-only from the local session store; no data was modified.

    1. No user-facing knob for compaction frequency

    I could not find any configuration key for compaction frequency or trigger thresholds. Checked and confirmed absent:

    • ~/.config/opencode/opencode.json
    • ~/.config/opencode/tui.json

    The only public extension surface I found is a pair of plugin hooks (dist/index.d.ts, @opencode-ai/[email protected]):

    • experimental.session.compacting — fires before compaction; its prompt can replace the summarization prompt wholesale
    • experimental.compaction.autocontinue — fires after compaction succeeds, before the synthetic continuation turn

    So the summarizer prompt appears to be customizable, but the trigger frequency is not. That matches the framing of this issue: the budget has to be correct in code, because a user can't compensate for it in config.

    I did not attempt to read app.asar for a config schema — it's a compiled Electron bundle and surface-inspecting it produced strings (allowCompact, reduceCompact) that sit in the same region as Effect-runtime internals, so I couldn't distinguish real config keys from library internals. I'm not claiming either way there.

    2. Observed compaction density (local DB, read-only)

    Path: C:\Users\Fisher\.local\share\opencode\opencode.db

    Measurement Value
    message rows (total) 23,189
    Compaction messages ("mode":"compaction" / "agent":"compaction" / "summary":true, all three co-occur) 1,380
    Distinct sessions containing ≥1 compaction 40 (of 300 sessions total)
    Most-affected session 308 compactions in a single session
    Next two highest 274 and 261 compactions
    session_context_epoch rows 0

    Exact-matching note, so the number isn't taken as inflated: I first counted with a loose LIKE '%compaction%' OR LIKE '%summar%' filter and got 5,351. That over-counts, because ordinary message bodies also contain the substring summar. The 1,380 figure comes from matching the exact JSON keys above; those three markers co-occur on the same 1,380 rows.

    Sessions hitting 300+ compactions is well outside what a single mis-sized output cap would explain as a one-off, and is why I'd treat this as a general budget problem rather than one model's configuration.

    3. One observation I can't yet interpret — session_context_epoch is empty

    The schema has the table with columns session_id, baseline, snapshot, baseline_seq, but it holds 0 rows across all 300 sessions, despite 40 of them having compacted.

    I don't know what populates it, so I'm not asserting a bug. If it's meant to track per-session compaction baselines, a permanently empty table alongside 1,380 compaction messages would suggest compaction baselines are never being recorded in the desktop build. Could a maintainer confirm whether this table is expected to be written, and by which code path? I'd rather ask than guess at a root cause.

    4. Question for the linked PR

    PR #51712 bounds the output reservation in usable() in packages/opencode/src/session/overflow.ts. Is the desktop app's compaction path going through that same function, or does the Electron build have a separate budget path that would also need the fix? If the latter, the fix may not reach desktop users without an additional change.

  3. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed write-up. The code you point to (packages/opencode/src/session/overflow.ts, processor.ts, flags.outputTokenMax) is OpenCode v1 (0.x/1.x, opencode-ai). v1 only gets fixes for critical bugs such as data loss, security problems or crashes. Compacting earlier than needed wastes context but doesn't fit that, so this is unlikely to be changed in v1.

    OpenCode v2 (@opencode/cli, 2.x) is a separate implementation (packages/core/src/session/compaction.ts), and it works out the threshold differently. It doesn't subtract the model's full output limit from the window. It reserves either your configured compaction buffer or a bounded share of the window. A model with a 1M context and 512k output therefore shouldn't compact at around half the window there. Please consider upgrading to v2.

    If you think this is critical, or you see the same early compaction (or the input/context mismatch) on v2, please reply with your opencode --version, the provider and model, and the token count at which compaction triggered.

  4. opencodejr commented on Oct 29, 2026

    @opencodejr
    Contributor

    Closing this as not planned. The compaction budget code it describes (packages/opencode/src/session/overflow.ts, processor.ts) is OpenCode v1, which only gets critical fixes, and compacting too early doesn't count as critical. OpenCode v2 works out the threshold differently: it reserves a bounded amount of the window rather than the model's full output limit. Thanks again for the careful analysis. If you see compaction trigger too early on v2 (@opencode/cli, 2.x), please open a new issue with your opencode --version, the provider and model, and the token count at which it compacted.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions