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?
2 Comments
Additional evidence from local Codex rollout archives:
I checked existing and archived Codex Desktop thread rollouts to estimate the current user-visible cost of synchronous compaction on long-running threads. I only used metadata timestamps and event types, not transcript contents.
Scope:
~/.codex/sessionsand~/.codex/archived_sessionscompactedrecordsevent_msg: token_count, to the top-levelcompactedrecord as the best available proxy. Codex does not appear to persist a cleancontext_compaction_startedevent today.After excluding startup/fork artifacts under 5 seconds and >10 minute outliers:
| Sample | Count | Median | p75 | p90 |
| --- | ---: | ---: | ---: | ---: |
| All live-ish compactions | 811 | 54s | 67s | 84s |
| User threads only | 631 | 54s | 66s | 79s |
| Recent user threads since 2026-06-01 | 435 | 57s | 70s | 84s |
| Current
0.142.0user threads | 11 | 85s | 100s | 106s |For the specific long-running Codex customization thread where this proposal came up, I found two live compactions: about 101s and 58s.
This suggests the current synchronous compaction path commonly adds about 1 minute of visible delay, and current-version samples can be closer to 1.5 minutes. That is enough latency to make speculative/background compaction worthwhile if implemented conservatively.
This proposal would also help with a datapoint from #30194: in some long-context Desktop/worktree sessions, compaction may appear to run but the effective context usage does not meaningfully go down afterward.
That makes earlier/speculative compaction valuable not just for latency, but for avoiding the unrecoverable state where the eventual compaction either cannot run or does not reclaim enough usable context to continue. A useful acceptance criterion might be: installed compaction results must materially reduce effective context load, and stale/insufficient results should be treated as failed/fallback rather than as successful compaction.