openai / openai/codex

Codex Desktop 26.810: repeated compacted image snapshots grow rollout to 16.9 GB and app-server to 19.5 GB

Open
#39,013 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app
Dominant language
Rust
Stars
125k
Forks
19.5k
PR merge metrics
PR metrics pending

Description

What version of the Codex App are you using (From “About Codex” dialog)?

ChatGPT for macOS 26.810.52044 (build 6662); bundled codex-cli 0.148.0-alpha.9

What subscription do you have?

ChatGPT subscription (exact tier omitted for privacy)

What platform is your computer?

Darwin 27.0.0 arm64 arm

What issue are you seeing?

Summary

A long-running Codex Desktop thread produced a 16.94 GB rollout JSONL and caused the bundled codex app-server to peak at approximately 19.5 GB physical footprint. System swap reached 28.6 GB used on a Mac with 32 GB RAM, and the app crashed under memory pressure.

This is still reproducible on ChatGPT for macOS 26.810.52044 with bundled codex-cli 0.148.0-alpha.9.

Content-safe local evidence

The affected rollout is a user thread fork using multi-agent v2. No raw prompts, paths, screenshots, session identifiers, or private project content are included here.

  • Rollout size: 16,942,114,729 bytes
  • Compaction windows recorded: 798
  • Recent compacted.payload.replacement_history: approximately 20–21 MB per record
  • Images retained per recent compacted snapshot: 75–83 input_image items
  • Inline image data per snapshot: approximately 20.5 MB
  • More than 98% of the sampled replacement-history bytes were inline image data
  • Context remained near the limit: approximately 233k input tokens out of a 258.4k context window
  • codex app-server peak footprint: approximately 19.5 GB
  • System swap: 28.6 / 29.7 GB used
  • Sustained app-server CPU during history processing: approximately 111%

Two file descriptors for the same oversized rollout were open in app-server: one read descriptor and one write descriptor.

A symbolized macOS process sample showed the active path passing through:

tokio::fs::file::File::poll_read
serde_json::read::StrRead::parse_str
serde::private::de::content::content_clone
codex_app_server::thread_state::ThreadState::track_current_turn_event
codex_app_server_protocol::protocol::thread_history::ThreadHistoryBuilder::handle_event

Allocator inspection showed a large transient allocation peak followed by substantial empty/fragmented small-allocation arenas. This looks like unbounded history materialization and cloning plus allocator fragmentation, rather than a small conventional object-retention leak.

Why this appears pathological

Each compaction persists another full replacement-history snapshot containing dozens of historical inline images. Because the post-compaction context remains close to the context limit, the thread compacts repeatedly without converging to a small checkpoint. Opening or continuing the thread then makes app-server parse and clone a multi-gigabyte append-only history.

What steps can reproduce the bug?
  1. Create or continue a Codex Desktop thread that uses repeated image/browser tooling.
  2. Allow the thread to run long enough to compact many times.
  3. Fork or continue the thread with full history.
  4. Observe that compacted replacement_history retains the historical inline input_image data.
  5. Continue until the post-compaction context remains close to the model context limit.
  6. Quit and reopen Codex Desktop, or reopen the affected thread.
  7. Observe app-server reading the oversized rollout, high CPU, a large transient heap, heavy swap growth, and eventual memory-pressure failure.

The private session identifier and local file path are intentionally omitted. I can provide additional sanitized aggregate measurements if useful.

What is the expected behavior?
  • Compaction should remove, externalize, summarize, or deduplicate historical inline image bytes.
  • Superseded compacted checkpoints should not remain on the active hydration path.
  • Resume and thread-history pagination should stream or use a persisted index instead of fully materializing and cloning the rollout.
  • Codex should enforce per-record, per-thread, and retained-media limits.
  • One oversized thread should fail safely with an actionable warning instead of destabilizing the app and operating system.
Additional information

This appears closely related to:

  • #34863 — compacted records retain repeated inline PNG data and drive app-server to 27 GB
  • #28866 — resume can OOM on very large local session JSONL
  • #34915 — thread-history pages repeatedly rebuild from large rollout JSONL files
  • #34268 — full-history forks duplicate historical compaction snapshots and inline images
  • #33493 — retained input images keep post-compaction context near the threshold

The reason for filing this separately is that the failure persists on the newer 26.810 / codex-cli 0.148 build, and this report includes a symbolized deserialization/history-builder stack plus a measured 798-compaction case.

Privacy note: the original rollout contains private prompts, local paths, tool output, and screenshots. It will not be uploaded publicly. All measurements above were collected using bounded, content-safe sampling.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the named deserialization path through tokio::fs::file::File::poll_read, ThreadState::track_current_turn_event, and ThreadHistoryBuilder::handle_event, using the related issues for context. Measure how compacted replacement_history and inline input_image data are materialized during resume and history handling. Done should prevent repeated historical image retention and avoid fully materializing oversized rollouts, while failing safely with an actionable warning.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend, performance
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.