The Codex context indicator shows 55% used, nearly half the window is still free, and Compacting... shows up in the middle of the task anyway. You are not imagining it: the counter that decides compaction is not the number the UI shows, and in that counter the model's past reasoning is added twice.
This guide explains where the gap comes from, how to recognize the case and what you can configure today so compaction stops catching you mid-work. Everything was checked against the source of the openai/codex repo, at tag rust-v0.163.0 (current stable) and on main, on 2026-10-18.
Why does Codex compact the context at 55% usage?
Because the compaction counter adds an estimate of past reasoning on top of the total the server already reported, and that total already includes that reasoning. The result crosses the limit long before the bar fills up.
From codex-rs/core/src/context_manager/history.rs:
if server_reasoning_included {
last_tokens.saturating_add(items_after_last_model_generated_tokens)
} else {
last_tokens
.saturating_add(self.get_non_last_reasoning_items_tokens())
.saturating_add(items_after_last_model_generated_tokens)
}
Codex only skips the estimate when the server says, through the x-reasoning-included header, that reasoning is already in the total. In the reproductions posted on issue #53913, that header was missing from both the connection and the response metadata. Without it, every encrypted reasoning item from earlier turns is estimated from its content length and added again.
How much it inflates the count
The numbers below were reconstructed by the issue authors themselves, with the sum landing exactly on the compaction trigger:
| Case | Bar showed | Estimate added again | Compaction counter | Limit |
|---|---|---|---|---|
| #53309, 1M window configured | 459,164 (about 55%) | 324,498 | 788,399 | 784,800 |
| #53913, 500k window | 255,367 (54%) | 200,147 | 455,514 | 450,000 |
Other reports on the same issue, between Oct 15 and 17, 2026, show compaction at 56%, 65% and 66% usage, including on Codex CLI 0.163.0. All of them with gpt-6.1-sol at high effort or above.

How do I know this is the problem?
Three signs together: compaction starts well below 90% on the bar, the session is long and reasoning effort is high or above. Check the version and the effort:
codex --version
grep -E 'model_reasoning_effort|model_auto_compact_token_limit|model_context_window' ~/.codex/config.toml
The longer the conversation and the higher the effort, the more reasoning items pile up, and the bigger the share counted twice. Short sessions or low effort barely feel the bug.
Does raising model_auto_compact_token_limit fix it?
No. The configured value is capped at 90% of the context window, so a bigger number does not push the trigger further out. From codex-rs/protocol/src/openai_models.rs:
let context_limit = self
.resolved_context_window()
.map(|context_window| (context_window * 9) / 10);
...
config_limit.map_or(context_limit, |limit| std::cmp::min(limit, context_limit))
One report (#54825) tried up to the largest 64-bit integer and the effective limit stayed at 90%. There is also no config.toml key to turn automatic compaction off.
How do I work around premature compaction in Codex?
You can shrink the double count and choose when compaction happens. Three adjustments, from simplest to finest.
1. Lower the reasoning effort
The estimate grows with the size of stored reasoning, so less reasoning per response means less double counting. In ~/.codex/config.toml:
model_reasoning_effort = "medium"
Or switch it for the session only with /model. Keep high for the stretch that needs it, not for the whole conversation.
2. Compact yourself, at a good pause
The worst part of automatic compaction is landing in the middle of a long task. Before asking for a big change, run:
/compact
You pick the moment, the task starts with only the summary in context, and the odds of it being interrupted drop.
3. Turn on end-of-turn compaction
Codex has a key that compacts after the final response, while you are between tasks, instead of waiting for the mid-work trigger:
model_post_turn_compact_threshold_percent = 70
The value is the percentage of the usable window that triggers this compaction, from 0 to 100. Zero or missing turns it off. It uses the same inflated counter, so it does not fix the count; what changes is the timing: compaction happens at the pause, not in the middle of the next task.
When will the official fix ship?
It has not shipped. Issue #53309 has been open since Oct 12, 2026, and the same code that adds the estimate is still on main as of Oct 18, with no OpenAI fix PR linked to it. Follow the issue and, once the fix reaches a stable release, set the effort back to what you used before.
Before compacting, it pays to look at what is actually filling the context. In Verboo Code, /context shows you, and /compact runs when you decide.



