Skip to content

Old Base64 images occupy 99.6% of chat history, making successive agent loops extremely slow #46761

Open

Description

@oyishyi

What issue are you seeing?

Long-running conversations with images become extremely slow because successive agent loops keep sending very large requests containing historical image data. The main impact is the repeated upload delay before the next model response: ordinary coding steps become painfully slow even when they do not require looking at those old images again.

In an inspected chat-history snapshot, 99.6% of the serialized history consisted of inline Base64 image data. Keeping old screenshots embedded in the history and repeatedly transferring them seems unreasonable for an interactive coding agent.

Measurements

  • The inspected history retained 30 user-uploaded images, represented as data:image/png;base64,..., totaling 39,408,084 bytes (37.58 MiB). These image data URLs accounted for approximately 99.6% of the serialized history snapshot.
  • Image hashes matched an earlier snapshot, confirming that the same image bytes were still present.
  • During one 30-minute window, local request logs recorded 64 model requests, with compressed request bodies totaling 2,780.74 MiB (2.716 GiB).
  • Individual compressed request bodies were approximately 49.9 MiB, reaching 78.34 MiB after additional screenshots were read. Other requests in the window were still around 27.6–28.6 MiB.

The recurring payload size is consistent with the severe per-loop slowdown I experience. I have not separately measured upload time versus server processing time, so these numbers do not establish an exact latency breakdown. The totals above are logged request-body sizes, not packet-capture measurements.

What steps can reproduce the bug?

  1. Use a Codex desktop conversation for a long-running coding task.
  2. Attach screenshots and reference images over multiple turns, and let tools return additional screenshots.
  3. Continue ordinary coding work, such as editing files and checking logs, without asking to inspect the old images again.
  4. Observe repeated large model requests and increasingly slow progress between agent steps.
  5. Inspect the history and request-size logs: old inline image data dominates the history, while successive requests remain tens of MiB in size.

What is the expected behavior?

Previously supplied images should be reusable through stable references or attachment IDs instead of requiring their full contents to be uploaded again for each model call. Older images could also be loaded on demand when needed.

Please provide a supported way to remove old image payloads from the active context while preserving the text conversation. Showing request size and distinguishing upload time from model processing would also make this slowdown easier to diagnose.

Environment

  • Codex desktop app on Windows x64.
  • Affected bundled runtime: 0.155.0-alpha.9. This is the runtime version, not the desktop app's About-dialog version.
  • Measurements taken on September 18, 2026.

Related reports: #35732 and #45109. This report adds a measured 99.6% image-data share and request-size totals, with emphasis on the latency of each agent loop.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    contextIssues related to context management (including compaction)
    on Sep 20, 2026
  2. github-actions commented on Sep 20, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. chipfighter commented on Sep 29, 2026

    @chipfighter

    Those numbers match what I measured on the Windows desktop app. Whenever the full history is sent, every image in it goes out again, so 30 screenshots cost ~40 MB per step even when the step never looks at them.

    While this is open, I built an open-source plugin for the Codex desktop app that lets you choose which past images are still sent (disclosure: I'm the author): Codex Attachment Manager.

    • A tab in the side panel lists every image in the task with its size. Uncheck the old ones, and from the next message on a local proxy replaces them with short placeholders before the request leaves your machine. The task and the conversation stay the same, and the rollout on disk isn't modified.
    • In a 15-image test, the next request went from 24.9 MB to 212 KB. The panel shows the estimated size of the next request, so you can see the effect before you send.
    • The model is told the images were left out on purpose. If it needs one again, it replies need IMG-xxx, and you check it back.

    Limits: it changes only what is sent, not the history on disk; it works with the default OpenAI backend only; tested on Windows with Codex 26.924, while macOS and Linux only pass CI so far.

    Install it from Codex's Plugins page (add the marketplace chipfighter/codex-attachment-manager) or with the one-line command in the README.

    The panel's filter shows only the PDF page, then every image again, and the uploads are unchecked a turn at a time. Asked about the chat button in the v1 desktop mockup, the model replies need IMG-001; the panel points to IMG-001, the user checks it, and the model answers from the image: orange.

  4. xiao-do-do commented on Oct 2, 2026

    @xiao-do-do

    This report captures the practical problem well: repeated historical-image transfers can dominate an interactive workflow even when the next step is an ordinary conversation turn. I am seeing the same class of efficiency problem on macOS during multi-round image generation.

    I am also affected on macOS while iterating on image generation across multiple turns. After reconnect attempts reach 5/5, the transport falls back to HTTP/SSE. Continuing the same conversation then causes repeated large image uploads, heavy bandwidth use, and substantial delays between turns. This severely affects Codex conversation efficiency and makes iterative design work difficult, including ordinary follow-up messages after image generation.

    Please correlate this with #38846 (WebSocket close code 1009 / message too big), #24550 (large inline-image history causing WebSocket fallback), and #23665 (recovery from HTTP fallback). A 1009 close and the subsequent HTTP/SSE fallback are different stages of the failure: an oversized WebSocket message can trigger the disconnect, and fallback can then expose the repeated full-history upload cost. I have not captured the close code from my own session, so I am reporting the retry/fallback and bandwidth symptoms rather than claiming a confirmed 1009 reproduction.

    Your cumulative request-body measurements are especially useful for showing why per-request compression alone is insufficient. Please track aggregate serialized image bytes and cumulative retransmission, provide a supported way to remove stale image data from active context, and preserve the text conversation when recovering from transport fallback. The measurements in this issue are the reporter's, not measurements from my machine.

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)performancewindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions