Feature proposal: speculative pre-turn compaction for long-context sessions
Problem
Auto-compaction currently runs when Codex is already at the compaction threshold. For long sessions, this can make the next turn stall while Codex performs a full compaction request synchronously.
I would like to propose a conservative speculative-compaction design: prepare a compacted summary in the background once a thread crosses an earlier threshold, then install it later only if it is still valid.
Proposed behavior
When a completed turn crosses a configurable precompute threshold, Codex starts a background remote-v2 compaction for the frozen history prefix.
Later, when normal pre-turn auto-compaction would run, Codex can install the prepared result instead of waiting for a new compaction request.
If the prepared result is stale, incomplete, failed, too large, or not applicable, Codex should fall back to the existing synchronous compaction path.
Suggested initial scope
Keep the first version intentionally narrow:
- pre-turn auto-compaction only
- remote compaction v2 only
- default off behind an under-development feature flag
- no mid-turn speculative install
- no token-budget reset mode change
- no user-visible history rewrite outside the existing
CompactedItem/replace_compacted_historypath
This avoids changing the current mid-turn compaction invariants, where replacement-history placement is more sensitive.
Safety / correctness checks
A prepared compaction result should only be installed when:
- the current context window id still matches
- the model/provider/compaction hash still match
- the current history still starts with the exact frozen prefix
- the replacement history estimate remains under the relevant auto-compact limit
- pre-compact hooks allow installation
Otherwise, fallback should use the current compaction behavior.
Possible config shape
[features.speculative_compaction]
enabled = true
trigger_ratio = 0.75
install_wait_ms = 100
trigger_ratio would apply to the existing auto-compact limit. For example, if auto-compaction is configured around 80% of the context window, 0.75 prepares around 60%.
Why this seems aligned with the current code
The current code already has the needed primitives:
- token status calculation in
session/context_window.rs - auto-compaction dispatch in
session/turn.rs - remote-v2 compaction request/build path in
compact_remote_v2.rs - durable replacement through
Session::replace_compacted_history - context-window IDs in
AutoCompactWindow - session-owned background task precedent in
session_startup_prewarm.rs
The proposal should reuse those instead of introducing a parallel transcript-rewrite path.
Tests that should cover the change
- precompute starts after threshold crossing without emitting compact lifecycle events
- prepared result is consumed by the next pre-turn compaction
- stale prefix falls back to normal compaction
- failed background compaction falls back
- replacement estimate over limit falls back
- mid-turn compaction ignores speculative result
- hooks run only during actual install
- persisted replacement history resumes correctly
Related context
This proposal is related to context/compaction performance and reliability issues, but is narrower than changing compaction quality or compaction prompts generally.
Related issues that seem adjacent:
- #27545: auto-compact fires post-sampling causing inflated token costs
- #29356: context compaction loses operational continuity in long tasks
- #29816: additive compaction guidance without overriding the built-in prompt
- #29947: context burn remains high after compaction/new session
Maintainer questions
- Should this be a new feature flag, or should it live under an existing compaction/token-budget feature?
- Is remote-v2-only acceptable for the first implementation?
- Would telemetry for prepared/used/stale/failed/fallback outcomes be required before considering this behavior?
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗