I Blamed Codex for My Token Costs. I Was Looking in the Wrong Place.
I blamed Codex for heavy token use, then saw the same pattern in Claude Code. Regular 400k auto-compaction, durable Shipwright iterate state and model roles for execution and review doubled my effective usage in early measurements.

Date
In my last article about five days with Codex, I wrote that I hit the weekly limit sooner than I expected. The observation was real. My conclusion was too simple.
I had treated the token consumption as evidence that Codex itself was the problem. Then I returned to Claude Code and ran into the same pattern. Long-running work, too much inherited history, expensive sessions and a usage window that disappeared faster than it should. The agent had changed. The problem had not.
That was a useful correction.
The relevant question is not whether an agent has context. Of course it needs context. The relevant question is which context it carries into every next exchange, which information can stay on disk until it is needed, and when a long conversation should deliberately become a smaller, well-documented one.
After changing that management in both Claude Code and Codex, my first measurements point to at least a factor-of-two improvement. In practical terms, the window until my included usage is exhausted has effectively doubled. It is an early measurement from my own workflow, not a universal benchmark. But it is large enough that I no longer think of token pressure as a Codex-versus-Claude problem.
The expensive thing is not a large file
It is tempting to look for one guilty object: a very long decision log, an event history, a large `AGENTS.md`, or a project with many skills. Those things can matter, but size on disk is not the cost by itself.
What costs tokens is the repeated combination of exchanges and carried context. A file that never enters a session adds no incremental cost to that session. A much smaller file that is loaded on every turn does. The same is true for tool output, long terminal transcripts, planning conversations and every piece of state that stays alive while a task grows.
OpenAI describes the same underlying mechanics for Codex: the prompt for a subsequent conversation turn includes previous messages and tool calls, so it grows with the conversation. Its agent loop must manage the context window for exactly that reason. Unrolling the Codex agent loop makes the point particularly clear.
Claude Code documents the same picture from the other side. Its context window includes instructions, files read during the session, responses and information that never appears in the terminal. A subagent has its own context window, which is why a large research read does not have to remain in the main conversation. Explore the context window is a useful interactive explanation.
The mental model I now use is simple: context is working capital. It is valuable when it helps the next decision. It becomes waste when it is carried forward only because nobody decided what to retain, summarise or reload on demand.
The correction to my Codex article
The earlier article was still right about one thing: a harness has a learning curve. Permissions, interaction style, project instructions and the way a tool presents its work all affect whether it feels natural.
But I mixed two different questions together.
One question is whether Codex and Claude Code suit my way of working equally well. That remains a legitimate, personal evaluation. The other is whether I was consuming tokens inefficiently. That was largely a context-management issue in my own workflow. Blaming one harness for it was not fair.
The correction matters because it changes the remedy. Switching tools does not solve a workflow that keeps loading more history than the next decision requires. I saw this directly once the same behaviour appeared in Claude Code.
It also makes the comparison more honest. Both systems offer compaction. Both let users provide persistent project guidance. Both can split work into separate contexts. The concrete configuration differs, but the operating discipline transfers.
Compact regularly and let Shipwright carry the state
The first change was to make auto-compaction an explicit, regular part of the workflow. In my setup, the window is set to 400k. That is not an emergency brake for when a session is already full. It is a chosen operating interval: enough room for meaningful work, followed by a predictable reduction of the conversation history.
Compaction is not throwing work away. It replaces a long conversation with a smaller representation of what the agent needs to continue. Both Codex and Claude Code can auto-compact as the context window fills. Claude Code also lets users define the auto-compact window explicitly. Claude Code's context-window documentation and its environment-variable reference explain those controls.
The important part is not a generic instruction to write a few notes to disk before compacting. Shipwright's `/shipwright-iterate` workflow already persists the state that is relevant to an iterate as it is produced. The conversation is not the single source of truth.
For an iterate, this durable state includes:
- the mini-plan, including small iterates that use the protocol
- the iterate specification, acceptance criteria and work status when the run requires them
- decision drops and the indexed decision history
- raw review payloads and the per-review-type
reviews.jsonrecord - the session handoff and the durable progress information needed for a resumed run
This was not just a design preference. The Shipwright change "make an interrupted iterate resumable from disk alone" closed concrete gaps exposed by mid-phase auto-compaction. It made mini-plan persistence consistent, required review findings to be materialised immediately, added a `SubagentStop` salvage hook for the narrow gap between a reviewer's return and the write, and made resume logic read `reviews.json` directly rather than trust a stale handoff snapshot.
That is the distinction I missed before. Regular compaction is entirely compatible with rich context when the workflow has durable, structured state to reload. Claude Code explicitly distinguishes what survives compaction from what is reloaded from disk. Its hooks documentation also shows that compaction has explicit before and after lifecycle events, which makes this an operating model rather than an accident at the end of a session.
An index is often more useful than another summary
The second change was about the decision log.
Shipwright records decisions so that the work can be understood later. That is exactly the kind of context I do not want to lose. But a growing decision log does not need to be read in full at the beginning of every session.
The useful pattern is an index plus detail on demand. The index contains the title, a one-line decision summary and a stable anchor for each entry. It is small enough to load by default. When the current task touches an earlier decision, the agent follows the anchor and reads the complete entry only then.
This is not an attempt to make the agent remember less. It is a way to let it retrieve more precisely.
Our Shipwright measurements give practical warning signs, not universal thresholds. At roughly 35 KB of decision history, it is sensible to set an explicit auto-compact window before the log becomes a repeated cost. Once a regularly loaded decision history reaches around 100 KB, an index begins to pay for itself. Past 2'000 lines, a single file-read operation may not even return the complete document. At that point, a request to "read the whole log" is not a strategy. The index-and-detail pattern is the only reliable way to reach the relevant information.
The numbers will differ in another repository. A terse decision log, a verbose one and an event-heavy project reach those points at different times. The transferable idea is to measure the material that is always loaded, then replace bulk loading with a compact map and targeted retrieval.
OpenAI makes a related recommendation for Codex: `AGENTS.md` should provide persistent repository context that the code cannot infer for itself. How OpenAI uses Codex is a useful reminder that persistent guidance is valuable. The distinction is that persistent does not have to mean ever-growing and fully loaded.
Give models roles instead of switching them mid-conversation
The third change was how I use model tiers.
The model split applies to both harnesses. In my Shipwright configuration, Claude Sonnet 5 executes and Claude Opus 5 reviews. In Codex, GPT-5.6 Terra executes and GPT-5.6 Sol reviews. The exact model names will change over time. The role split is the point.
These are defaults, not a fixed doctrine. Shipwright exposes execution, review, plan-review and finalisation as separate roles in `shipwright_model_config.json`, so one can configure the combination that fits the available access, cost profile and risk tolerance. Routine execution benefits from a capable, efficient model with a bounded task. Review benefits from a stronger, more critical pass that can question the result. Those should be separate contexts, not a mid-session model swap.
Why? A long conversation carries an expensive prompt prefix. Changing the setup in the middle can invalidate the cached prefix, which means paying to establish it again. OpenAI notes that even a change in how tool definitions are ordered can create a costly cache miss. That is a useful warning about treating a long session as if it were free to reconfigure. The Codex agent-loop article explains the team's care around cache hits.
There is a second advantage. A separate review is genuinely independent. It receives the implementation, the relevant decision index and a focused review question. It does not need to carry every exploratory tool call from the build phase in order to do useful work.
Context remains key
None of this means that an agent should work with less context for its own sake. Context remains key. Removing relevant decisions, requirements or evidence would simply move the cost into misunderstandings, repeated investigation and weak decisions.
The goal is to keep context rich where it informs the next decision, while making the complete iterate recoverable from durable Shipwright artefacts:
- durable decisions instead of long conversational memory
- an index by default, full history only when it is relevant
- regular auto-compaction with durable iterate state
- separate contexts for different roles
- a fresh session for unrelated work
That combination is now part of how I operate Shipwright. The framework already treats development as a sequence of explicit phases and artefacts. Adding disciplined context management makes that workflow more economical without making it less informed.
What I would measure before judging a tool
My original weekly-limit comparison was useful as a signal that something deserved investigation. It was not useful as a verdict on Codex.
If I compare agent tools again, I will first look at the shape of the work: number of exchanges, volume of tool output, always-loaded project material, where compaction occurs, and whether execution and review have been separated. Only then does the usage number say something about the harness.
The first result is encouraging: at least twice as much effective usage before the included allowance runs out. I want more observations before I turn that into a general claim. But the direction is already clear.
My correction to the Codex article is therefore straightforward: the token cost was not primarily evidence that Codex was worse. It was evidence that I had not yet managed context deliberately enough. Claude Code gave me the same lesson. Both tools benefited when I changed the workflow.
---
Sources:
- Unrolling the Codex agent loop - OpenAI - accessed 10 August 2026 - https://openai.com/index/unrolling-the-codex-agent-loop/
- How OpenAI uses Codex - OpenAI - accessed 10 August 2026 - https://cdn.openai.com/pdf/6a2631dc-783e-479b-b1a4-af0cfbd38630/how-openai-uses-codex.pdf
- Explore the context window - Claude Code Docs - accessed 10 August 2026 - https://code.claude.com/docs/en/context-window
- Environment variables - Claude Code Docs - accessed 10 August 2026 - https://code.claude.com/docs/en/env-vars
- Hooks reference - Claude Code Docs - accessed 10 August 2026 - https://code.claude.com/docs/en/hooks
- fix(iterate): make an interrupted iterate resumable from disk alone - Shipwright - 9 August 2026 - https://github.com/svenroth-ai/shipwright/commit/dd3d39a2580dc39109796c0990c2117e32146600
