Feature proposal: speculative pre-turn compaction for long-context sessions

Open 💬 2 comments Opened Jun 25, 2026 by NaxAlpha

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_history path

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?

View original on GitHub ↗

2 Comments

NaxAlpha · 2 months ago

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:

  • Scanned ~/.codex/sessions and ~/.codex/archived_sessions
  • 1,486 rollout files
  • 976 compacted records
  • Used the gap from the last pre-compaction rollout event, usually event_msg: token_count, to the top-level compacted record as the best available proxy. Codex does not appear to persist a clean context_compaction_started event 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.0 user 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.

devansh-jain-18 · 2 months ago

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.