Skip to content

Local compaction v2 retains unbounded input_image payloads, causing repeated auto-compaction #33493

Description

@snrui

What version of Codex is running?

  • Codex Desktop: 26.707.72221
  • Embedded CLI: codex-cli 0.144.2
  • Platform: macOS 26.3 (Build 25D125), Apple Silicon
  • Model: gpt-5.6-sol

What issue are you seeing?

A long-running, image-heavy Codex Desktop thread enters a repeated auto-compaction cycle. After a compaction completes, the resulting history remains only slightly below the auto-compaction threshold. Even a short new question pushes it over the threshold again, so almost every new turn starts with another compaction.

The compacted replacement_history keeps historical input_image items, including their full inline base64/data-URL payloads. Repeated compactions keep copying the same images into new compacted records.

This produces two related effects:

  1. The post-compaction prompt remains close to the context threshold, causing immediate re-compaction on subsequent turns.
  2. The rollout JSONL grows rapidly because the same inline image payloads are persisted repeatedly.

Local evidence

From one affected thread:

Metric Observed value
Rollout JSONL size approximately 4.16 GB
Compaction records 224
Images retained by the latest compacted replacement history 92
Retained inline image/base64 characters approximately 26.47 million
Retained text characters approximately 188,000
Effective context window reported for the session 258,400 tokens
Default auto-compaction threshold approximately 244,800 tokens
Prompt size immediately after compaction approximately 236,000-237,000 tokens

The post-compaction history therefore has only about 8,000 tokens of headroom. A normal follow-up turn is sufficient to trigger compaction again.

No full rollout is attached because it contains private prompts, paths, tool output, and images. I can provide additional redacted structural statistics if needed.

Steps to reproduce

  1. Use a long-running Codex Desktop thread containing multiple pasted screenshots or image inputs.
  2. Continue until local/remote-v2 compaction occurs.
  3. Inspect the newest type: "compacted" rollout record.
  4. Confirm that payload.replacement_history retains user messages containing input_image data URLs.
  5. Send a short follow-up question.
  6. Observe another automatic compaction even though the previous compaction just completed.
  7. Repeat several turns and observe the rollout file growing as image payloads are copied into additional compacted records.

Expected behavior

After compaction:

  • Retained multimodal history should be bounded by a realistic image/token/byte budget.
  • There should be enough hysteresis below the auto-compaction threshold for ordinary follow-up turns.
  • Old inline image payloads should not be duplicated indefinitely in every compacted rollout record.

Actual behavior

The current retained-message text budget treats images as zero text tokens and preserves them:

ContentItem::InputImage { .. } => 0,

and later:

ContentItem::InputImage { .. } => truncated_content.push(content_item),

The message-level .max(1) floor limits the number of image-only messages only very weakly. It does not account for image cost inside mixed text/image messages, image count, encoded byte size, or vision-token cost.

Current source:

  • codex-rs/core/src/compact_remote_v2.rs
  • message_text_token_count
  • truncate_message_text_to_token_budget
  • truncate_retained_messages_for_remote_compaction

Possible fix direction

For active compacted history:

  1. Give retained images a conservative estimated token cost, using the existing image-size/detail estimator where possible.
  2. Add explicit caps for retained image count and/or encoded bytes.
  3. Keep the newest images first and replace older images with a lightweight placeholder once the image budget is exhausted.
  4. Add a regression test with many mixed text/image messages verifying that compacted history is bounded and a short next turn does not immediately trigger compaction again.

For rollout persistence, consider storing images as content-addressed blobs or references rather than repeating full base64 strings. That storage concern may be better handled separately under the existing image-heavy rollout issue.

Related issues

I am willing to help with additional redacted diagnostics, test-case design, or an implementation if maintainers agree on the approach and invite a PR under the repository contribution policy.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingcontextIssues related to context management (including compaction)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions