Repository navigation
Severe CLI reliability failure: 63.8 MB image-history requests before any compaction, WebSocket fallback, and prolonged stalls on Windows #43015
Description
Summary and urgent request
Please urgently investigate aggregate image-history byte growth and the repeated full-request cost after WebSocket fallback, and provide a supported recovery path for affected sessions.
In a real image-assisted coding task, Codex accumulated 63,759,837 bytes per request, still 45,853,691 bytes after zstd compression. At the corresponding history snapshot, 38 typed image occurrences accounted for 61,279,872 ASCII data-URL characters. This happened before any compaction, not only through images retained in an old compacted replacement history.
The failure had a serious practical impact: repeated stream errors, five-attempt retry batches, HTTPS fallback, and prolonged periods in which the primary task did not advance. One failed sequence on 0.153.2 lasted approximately 88 minutes without new effective model output. Updating to 0.153.4, the latest stable release when checked on September 5, did not remove the accumulated payload or prevent the observed WebSocket fallback.
I am extremely dissatisfied with this experience. These failure periods made Codex CLI effectively unusable for my paid development workflow. Waiting through prolonged retries without an actionable explanation or reliable recovery procedure is unacceptable. Users should not need to inspect SQLite databases, count Base64 payloads, or study client source code merely to keep an image-assisted coding task usable. I am asking for urgent maintainer triage, a supported mitigation, and a prioritized fix—not merely another generic reconnect warning.
The report also includes a later partial recovery: a successful compaction removed the old tool-image payloads from active replacement history and work resumed. I am not claiming permanent data loss or that every use of view_image fails.
Related reports and the additional evidence here
This is closely related to #41338 and #24550. Please consolidate this evidence into an existing tracker if that is the preferred triage path.
The distinguishing measurements are:
- Windows, the built-in OpenAI provider, ChatGPT authentication, and current stable 0.153.4—not a Responses-to-Chat bridge.
- Zero compaction records at the failure snapshot: ordinary current-window image outputs can already create the large-request condition.
- 37 distinct data URLs across 38 occurrences. Exact deduplication would remove only 1,119,846 bytes, or 1.83% of the image data.
- The largest individual data URL was 5,183,170 bytes. None exceeded 10 MiB. A per-image 10 MiB ceiling alone would not address this workload.
- Actual pre/post-compression request measurements, separately from rollout file size and token accounting.
- A subsequent compaction that can be inspected structurally: tool-output images were removed, while the original user-message images remained.
Environment
| Field | Observed value |
|---|---|
| Codex CLI | 0.153.2 during the original long failed sequence; upgraded to 0.153.4 before the later resumed failure |
| Current stable release checked | rust-v0.153.4, published September 4, 2026 |
| Source version audited | 3d2ee51ca2d5db578f328aa75e20aa22c0197c9a / rust-v0.153.4 |
| Platform | Windows x64, OS build 10.0.26100 |
| Shell | PowerShell 7.6; terminal-emulator version not collected |
| Subscription / authentication | ChatGPT Pro; ChatGPT authentication |
| Provider | Built-in OpenAI provider, Codex Responses endpoint |
| Model | gpt-6-astra |
| Reasoning selection | Initially xhigh; the resumed pre-compaction and post-compaction turns both used ultra |
| Service tier | default |
| Network | Explicit HTTP/HTTPS proxy variables pointing to a local v2rayN proxy; TUN/routing changes are disclosed below |
Relevant non-default context settings were:
model_context_window = 1000000
model_auto_compact_token_limit = 900000The session reported a model_context_window of 828,400. I am disclosing the configured values without asserting that they were the effective runtime limits. This is not a claim of reproduction with an untouched default configuration. It is a supported long-context workflow that lacked an effective safeguard against its much larger serialized image payload.
Codex doctor report
A new full codex doctor --json report was not collected for this investigation. The evidence below comes from targeted read-only inspection of the affected rollout, retained client logs, process/network state, and the pinned client source. I am not substituting an older doctor report or claiming that doctor passed.
What happened: measured request and history sizes
The HTTP client recorded the following at 2026-09-05 11:12:14 UTC:
Compressed request body with zstd
pre_compression_bytes=63759837
post_compression_bytes=45853691
compression_duration_ms=78
Several earlier requests in the same resumed task were almost as large:
| UTC | Before compression | After compression | Compression time |
|---|---|---|---|
| 10:55:20 | 63,721,050 B | 45,827,415 B | 70 ms |
| 10:57:42 | 63,740,637 B | 45,841,192 B | 76 ms |
| 10:58:22 | 63,742,371 B | 45,842,100 B | 70 ms |
| 10:59:43 | 63,742,371 B | 45,842,094 B | 98 ms |
| 11:12:14 | 63,759,837 B | 45,853,691 B | 78 ms |
These are application-recorded request-body sizes, not inferred wire traffic, billing totals, or the size of the JSONL file. Compression itself was fast; the measurements do not justify blaming local zstd work for multi-minute delays.
The corresponding history was inspected through 11:12:15 UTC, counting only response_item records:
| Typed image location | Occurrences | Data-URL characters / ASCII bytes |
|---|---|---|
User-message content[].image_url |
7 | 4,307,974 |
Function/custom-tool output[].image_url |
31 | 56,971,898 |
| Total | 38 | 61,279,872 |
All counted image values belonged to typed input_image objects. UI/event duplicates were not included in these totals. The main sources were generated images and image-viewing tool outputs; this is not a claim that the whole total came from view_image alone.
The last completed request recorded at 10:58:22 UTC reported 482,479 input tokens, of which 480,000 were cached. That is the last completed-request usage record, not a new usage measurement for the 11:12 submission. It demonstrates that high token-cache reuse coexisted with repeated large requests; unchanged usage counters do not prove the backend performed no work or incurred no cost.
Failure chronology and severity
All times below are September 5, 2026, UTC.
| Time / interval | Observation |
|---|---|
| 08:53:15–10:21:18, CLI 0.153.2 | After the last productive tool result, repeated response-stream failures produced no new effective model output for approximately 88 minutes; the turn eventually failed. |
| 09:08:19, 09:23:24, 09:38:29, 09:51:07, 10:06:11 | Five recorded retries in that failed sequence. The roughly 15-minute spacing is observed behavior, not a claim about a proven timeout setting. |
| 10:51–10:52 | CLI upgraded to 0.153.4 and restarted; the original session was resumed. |
| 10:53 | Multiple WebSocket handshakes succeeded; actual request sends then failed with Windows error 10054 and exhausted five retries. |
| 10:54:01 | HTTP fallback was activated. |
| 10:55–10:58 | Some productive tool activity resumed, including starting two subagents. |
| 10:59:43 | A separate manual route change restarted the proxy and caused a known disconnect. This event is treated separately, as explained below. |
| 11:00:19 and 11:12:44 | HTTPS requests received HTTP 200; SSE keepalives were also observed during long waits. |
| 11:07:35 and 11:08:44 | The two subagents completed; their progress must not be confused with the primary thread's progress. |
| 11:31:23–11:36:38 | The running turn was interrupted, then a compaction ran and completed. |
The errors included:
stream disconnected before completion:
failed to send websocket request: IO error: ... (os error 10054)
Falling back from WebSockets to HTTPS transport
stream disconnected before completion:
Transport error: network error: error decoding response body
The original 88-minute terminal failure occurred on 0.153.2. The later handshake/send failures, fallback and large requests were observed on 0.153.4. I am not attributing the earlier 88-minute sequence to the newer binary.
Later recovery: important evidence, not omitted
At 11:36:38, the completed compaction installed a replacement history containing:
- 36 items: 35 messages and one compaction item;
- 7 embedded images totaling 4,307,974 characters;
- approximately 4,378,186 bytes when serialized as compact UTF-8 JSON by the inspection code.
The retained image multiset exactly matched the earlier user-message image multiset. The old raw tool outputs were no longer present in the replacement history. Relative to the earlier snapshot, embedded image bytes decreased by approximately 92.97%.
Subsequent retained HTTP logs showed requests around 9.8–10.9 MB before compression, substantially below the earlier 63.8 MB, and the primary thread again performed commands and file edits. Those later requests already included additional post-compaction work, so they are not the size of the first untouched compacted request.
This is a natural before/after observation, not a controlled benchmark. The model selection remained Astra/Ultra and the same CLI process continued, but the workload changed and upstream conditions were not controlled. Long waits were not eliminated: one later parent-thread tool-result-to-next-tool-call interval was still about 11 minutes.
The observed recovery supports treating active-history size as an important contributor. It does not prove that compaction alone fixes every affected thread, or that every minute of delay was upload time. It also matches an important implementation distinction: current compaction can discard original tool outputs while retaining user images.
Reproduction conditions
The observed workload was:
- Run a long image-assisted coding session using the built-in OpenAI provider and the environment described above.
- Generate and inspect multiple images through normal tools. Retain several dozen prepared images in active history; individual images need not exceed 10 MiB.
- Continue model/tool iterations without a compaction having reduced that history.
- Resume the same history after a CLI restart.
- Compare request-body byte measurements with token accounting, and observe whether the actual resumed WebSocket request succeeds after the handshake.
This describes the real failure conditions. A standalone minimal deterministic network reproducer and a sanitized-copy A/B test have not been run. The private workload cannot be pasted into a public issue. The report is not evidence that every image, network, model, or default configuration reproduces the transport failure.
Technical assessment: what is proven, and what is most likely
Confirmed: this workload retained tens of megabytes of typed image data and repeatedly constructed very large requests. The current source explains how that payload survives truncation and is resent when the full-history path is used.
Most strongly supported explanation of the amplification: accumulated inline images become expensive repeatedly when incremental WebSocket continuation is unavailable and the client submits the full active prompt over HTTP. Additional images can enlarge subsequent submissions again. The natural compaction observation and related community controls support this explanation.
Not established: the exact origin of the first TCP reset, a particular server/proxy message-size ceiling, or a universal causal relationship between image size and every observed stall. Payload size or multimodal replay shape may trigger a transport/endpoint limitation, but local/upstream proxy behavior and backend processing are still possible contributors. High reasoning effort also contributes to ordinary model latency.
Pinned source evidence and the conditional byte-amplification argument
The following code was checked at release commit 3d2ee51ca2d5db578f328aa75e20aa22c0197c9a:
| Component | Relevant behavior |
|---|---|
| Image-viewing handler | Produces a data URL and a typed image output. Omitting the image from the log preview does not remove it from model input. |
| Tool-output truncation | Text is budgeted/truncated while InputImage URLs are copied in the inspected paths. |
| History/token estimation | Replaces the actual Base64 byte contribution with an image-token estimate. Correct token estimation still requires a separate serialized-byte safeguard. |
| Request construction and transports | HTTP constructs a request from the formatted active prompt. WS may use incremental input when prior-response state and prefix matching permit it; otherwise it uses full input. |
| Compacted-history retention | Filters ordinary raw tool outputs; retained user images can remain. Thus compaction outcomes depend on the history's shape. |
| WebSocket response stream | The ordinary Message::Close(_) branch discards close details and returns a generic stream error. This does not imply that our 10054 included a close frame. |
The deterministic part can be stated narrowly. Let b_i be the byte length of each prepared inline image URL retained in a history that is serialized in full. These strings must contribute at least sum(b_i) bytes to that uncompressed request, before surrounding JSON and other inputs. If the same image strings are retained across k such requests, they contribute at least k * sum(b_i) bytes across the constructed request bodies.
That is a serialization consequence under stated conditions. It is not proof that all requests reach the network in full, that those bytes are billable tokens, or that a connection must fail at a particular size. Compression and WS incremental continuation change transfer costs; the recorded zstd sizes establish the substantial cost in this case.
For this workload, a single-image ceiling and exact deduplication are insufficient on their own: no image exceeded 10 MiB, and 37 of 38 encoded images were distinct. The safeguard needs an aggregate/lifecycle dimension.
Confounders and limits explicitly checked
- Proxy route change: at 10:59:43, changing routing restarted Xray/sing-box and disrupted both the affected session and another active session. That disconnect is not used as proof of image-induced failure. Earlier failures predated it.
- Proxy configuration was present: explicit HTTP/HTTPS proxy settings were active and actual WebSocket handshakes succeeded. This differs from an older missing-proxy/handshake-timeout problem.
- Connection versus progress: HTTP 200 and periodic SSE keepalives demonstrate some established stream activity, not completion of model work. I am not calling every long wait a deadlock.
- Local resource evidence: the inspected snapshots did not show CPU/memory exhaustion; local request compression was measured in milliseconds. These snapshots do not exclude every possible local bottleneck.
- Billing: no monetary loss, duplicate model billing, or precise quota waste is claimed from the byte counts or unchanged usage counters.
- Recovery: a compaction later succeeded and work resumed. No permanent data loss or permanently unrecoverable session is claimed.
- Log retention: older retained-client-log rows rotated during the investigation. Their measurements were captured while present; the persistent rollout and saved diagnostic observations were cross-checked. No unrestricted packet capture or server-side trace was obtained.
Existing fixes and reports have been considered
| Reference | Relevance and boundary |
|---|---|
| #41338 | Directly reports the byte/token mismatch from local image viewing; open when checked. |
| #24550 | Reports WS retries/fallback with retained images. Its original compaction-specific reproduction differs from this pre-compaction case. |
| #30441 | Related image-history size failures; this local report does not claim a 413 was observed. |
| #24388 and closure response | Acknowledges an earlier compaction issue and explains a change in compaction implementation. This should not be read as confirmation that every image-byte retention problem is fixed. |
| Merged PR #38681 | Preserves parent HTTP fallback for delegated sessions. Its commit is an ancestor of 0.153.4 and the relevant code is present. I am not claiming that this specific fix is absent. |
In particular, I am not requesting that maintainers redo #38681. Please assess the remaining current-window byte growth and repeated full-history submission separately from already-addressed delegated-session fallback behavior.
Expected behavior and urgent requested action
Image viewing is a core, legitimate workflow. The expected solution should preserve useful visual capability rather than requiring users to avoid images altogether.
Please:
- Urgently triage and assign ownership for the aggregate image-history/request-byte problem, clarify which existing tracker owns it, and provide a current supported mitigation and expected fix/release path.
- Add an aggregate serialized-byte safeguard, independent of token budgeting, covering ordinary tool outputs before compaction as well as continuation, resume/fork and compacted history. Many individually small images must be covered.
- Provide a bounded lifecycle or out-of-band representation for older image artifacts, with explicit references and on-demand retrieval. Do not silently discard task-critical current images or the user's original files.
- Avoid repeatedly resubmitting a deterministically rejected large request unchanged. Preserve actionable close/status details when available; do not infer an oversize error solely from a generic TCP reset.
- Provide a supported recovery procedure for existing affected sessions, with preservation of project files and useful task context, instead of requiring manual JSONL/SQLite surgery or abandoning a long task without a reliable handoff.
- Make the UI distinguish connection attempts, accepted requests with heartbeats, actual model progress, and repeated request-size failure. Surface the relevant byte measurements and a useful recovery action.
Suggested regression coverage should include multiple sub-10-MiB images, current-window tool images before any compaction, high token-cache reuse with large serialized bodies, both user and tool images after compaction, and repeated continuation after fallback. Please verify both the request bytes and successful follow-up behavior; a low token count or a successful compaction notification alone is insufficient.
This is a serious interruption to paid, real development work, not a cosmetic warning. Please provide an actionable official response as soon as possible.
Privacy and supporting material
Only sanitized measurements and code references are included. Raw rollouts, images, prompts, project paths, credentials, cookies, account identifiers and private request IDs are intentionally omitted. Please specify an appropriate secure channel if additional private diagnostic material is necessary for triage.
Activity
FengYeeLx commentedon Sep 6, 2026
@kchainani-oai — apologies for the direct ping. I am mentioning you because you have very recently worked on Codex's core image-preparation path.
I would appreciate triage or routing to the current owner of image history / request construction. This report appears to expose a boundary that the existing retained-image compaction safeguards do not cover: aggregate serialized image growth in ordinary active history before any compaction has occurred.
The measured affected request reached:
63,759,837bytes before compression;45,853,691bytes after zstd;61,279,872data-URL characters across 38 typed image occurrences;5,183,170bytes;Exact deduplication would recover only about 1.83% of the image data in this workload. A single-image 10 MiB ceiling would also not prevent it.
The later successful compaction naturally reduced embedded image bytes by about 92.97% and productive work resumed, which further supports active-history size as an important contributor, while not proving that every observed transport stall was caused by payload size.
The key architectural concern is therefore not merely retained images after compaction. It is that model-token/context budgeting and actual serialized-request-byte growth can diverge substantially during a normal multimodal working window.
A new
codex doctor --jsondiagnostic was also collected in #43168. It reports the active ChatGPT provider endpoints as reachable and the Responses WebSocket handshake as successful.Additional internal diagnostics were uploaded through
/feedback:01a0755c-377e-75a1-9085-6f6a34bda5cfCould you please triage this or route it to the current owner of image preparation/history/request serialization? I am especially looking for a supported short-term mitigation and whether an aggregate active-history byte budget is already planned.
Related reports: #41338 and #24550.
Please help. @kchainani-oai
FengYeeLx commentedon Sep 7, 2026
Status update — 2026-09-07
I re-checked current
mainfor changes relevant to this report.There is now a potentially relevant under-development feature,
UnifiedImageBudget. Its source description is:It is currently marked
UnderDevelopmentanddefault_enabled: false, and the image-preparation path supportsImagePreparationMode::UnifiedBudget.This looks relevant and may materially reduce individual prepared image sizes. However, I cannot tell from the current implementation whether it is intended to solve the specific failure boundary demonstrated in this issue: aggregate serialized-byte growth across many images in ordinary active history.
That distinction matters here because the measured workload had:
So a per-image pixel/token policy may mitigate the magnitude, but it does not obviously provide a bounded aggregate serialized-request byte budget as the number of retained images grows.
There is also independent evidence in #41338 showing the same broader byte-vs-token asymmetry on macOS: one reported compacted history retained 23 complete PNG data URLs totaling 57,737,086 characters, producing a request of approximately 58.85 MB before zstd / 28.80 MB after zstd, with substantially worse time-to-first-reasoning than a fresh thread.
That cross-platform evidence makes this look less like a Windows-specific transport artifact and more like a general lifecycle/request-construction problem around inline image history.
Could a maintainer clarify whether
UnifiedImageBudgetis intended to cover the aggregate serialized-history/request-byte problem reported here?If it is not, I believe this issue still requires a separate aggregate/lifecycle safeguard — for example a serialized-byte budget, eviction/replacement policy, or out-of-band image representation — in addition to per-image preparation limits.
Latest stable remains 0.153.4.
FengYeeLx commentedon Sep 8, 2026
Follow-up — September 8, 2026
Hi @kchainani-oai — my apologies for one further mention, and thank you for your time.
Could you please help route this report to the appropriate owner of image-history retention or request construction? I appreciate that the report is recent. My immediate hope is to understand the supported mitigation and whether existing work already covers this failure boundary.
Following up on my September 7 note, the distinction I would particularly appreciate clarification on is aggregate serialized image bytes across active history, rather than only the preparation limits applied to each individual image.
The measured request was 63,759,837 bytes before compression and 45,853,691 bytes after zstd. The corresponding history contained 38 typed image occurrences with 37 distinct data URLs, before any compaction had occurred. No individual image exceeded 10 MiB. The original report also discloses the non-default context settings; I am not presenting this as an all-default-configuration reproduction.
At
maincommit3caf9f9586baedb4158a7b91545ead3dd320c348,UnifiedImageBudgetremains under development and disabled by default. The inspected preparation path processes images individually. I am therefore not treating it as a confirmed aggregate-byte mitigation or assuming that it necessarily reduces every image's serialized size.Is that feature intended to address the aggregate active-history/request-size problem, or does this need separate handling elsewhere? Guidance on a supported recovery path for already affected ChatGPT-authenticated sessions, without manually editing session files, would be especially helpful.
The associated diagnostic reference is recorded in #43168:
01a0755c-377e-75a1-9085-6f6a34bda5cfI would be happy to consolidate the evidence under #41338, #24550, or another tracker you recommend. Even a brief routing acknowledgment would help me avoid duplicating work or following the wrong mitigation.
Thank you again for your time and consideration.
NayaCcR commentedon Sep 8, 2026
Same issue here. Looking forward to a fix.@jif-oai @kchainani-oai
FengYeeLx commentedon Sep 8, 2026
@etraut-openai @bc-openai @riley-oai @rhan-oai @fcoury-oai @fchen-oai @felixxia-oai @jif-oai
I am deeply sorry for tagging so many of you at once.
I know this is intrusive, and I know that mass-mentioning maintainers is generally not an appropriate way to ask for help. I genuinely apologize for adding another notification to your workload. I would not do this under normal circumstances, and I do not intend to make a habit of it.
I am doing it only because I have run out of reasonable ways to determine how to get these two reports in front of the right person:
I have tried very hard to make both reports useful rather than simply reporting that “Codex is broken.” They include sanitized evidence, reproduction conditions, measurements, source-level observations, explicit limits on what the evidence does and does not prove, and suggested areas to investigate.
I also submitted an internal
/feedbackdiagnostic bundle and created #43168 solely so that the diagnostic thread could be associated with the two canonical reports.I understand that the Codex repository receives an extraordinary number of issues, that everyone here has their own responsibilities, and that many of you may have nothing to do with these particular components. I am not asking everyone I tagged to investigate the bugs, and I am absolutely not asking for an immediate fix or a release commitment.
I am asking for something much smaller:
If even one person here knows which engineer/team owns the relevant code, could you please help route these reports to them, or leave a brief indication of where I should take them?
Even something as short as:
or:
would be enormously helpful.
For #43022 in particular, I have tried to reduce the problem to a deterministic local transport experiment so that investigation does not depend on reproducing an intermittent production stall.
For #43015, I have tried to separate model-token accounting from aggregate serialized request size and to provide concrete byte measurements rather than speculation.
I am completely willing to provide additional sanitized diagnostics, run a narrowly specified experiment, test a candidate build, or correct anything in my analysis if I have misunderstood the implementation.
And if this mass mention itself is inappropriate, I sincerely apologize. Please feel completely free not to respond individually. I only need one route to the correct owner.
I care about Codex a great deal and use it heavily in real development work. My persistence here is not intended as criticism of any individual engineer. It comes from these failures having become serious workflow blockers for me, while I have been unable to determine any other reliable escalation path.
Again, I am very sorry for the broad notification, and I appreciate anyone who took the time even to read this far.
Thank you very much for your time, and please accept my apologies for the interruption.
FengYeeLx commentedon Sep 8, 2026
Follow-up: consolidated related-issue map across the full inline-image / history / compaction lifecycle
I am adding one final consolidated cross-reference map because there is now a substantial set of independent Codex reports covering inline image/media payloads at different stages of the history lifecycle.
I am not asserting that every issue below is a duplicate of #43015 or that every image-related stall has one identical root cause.
The important distinguishing evidence in #43015 remains:
Therefore this issue is specifically evidence that ordinary active history can already become pathologically large before compaction has occurred.
For clarity, the lifecycle can be divided into:
#43015 primarily demonstrates the missing Stage-B aggregate serialized-byte safeguard.
1. Strongest direct byte-vs-token and active-request corroboration
#41338 — Inline image output costs ~230 tokens but 4.2 MB on the wire
This is one of the strongest independent corroborating reports.
Eight
view_imageoutputs contributed approximately 33.6 MB while adding only 1,843 prompt tokens, directly demonstrating the mismatch between token-denominated context management and byte-denominated request/transport constraints.#28316 — Codex should not resend large base64 image tool outputs in subsequent context
Independent evidence that full Base64 image payloads can remain in historical tool messages and be resubmitted in later requests.
#37194 — Config option to keep generated-image base64 out of conversation history
Reports approximately 35 MiB of retained generated-image data causing WebSocket
1009, retry exhaustion and HTTP413in a custom-provider workflow.#30441 — Unbounded image history payload can make threads unrecoverable with 413
Proposes bounding large individual images and counting image URLs against truncation budgets.
Severe CLI reliability failure: 63.8 MB image-history requests before any compaction, WebSocket fallback, and prolonged stalls on Windows #43015 adds an important boundary to a purely per-image approach:
Therefore a 10 MiB per-image cap alone would not prevent the observed 63.8 MB aggregate request.
#38846 — Long CLI threads exceed Responses WebSocket message limit before auto-compaction
Diagnostic instrumentation exposed WebSocket close code
1009(Message Too Big) before the token-based auto-compaction threshold was reached.#24550 — Responses WebSocket falls back when compacted replacement_history contains large inline images
Strong copied-session A/B evidence. Removing only retained compacted images allowed the copied session to complete over WebSocket without retries/fallback.
#39499 — Full-history fork replays compacted inline images and closes Responses WebSocket before response.completed
Demonstrates another full-history replay route where large inline image records interact with Responses WebSocket reliability.
#40608 — Windows App dragged image attachments trigger WebSocket 10054
Relevant current Windows evidence around inline attachment bytes and WebSocket failure.
These reports span different surfaces/providers and should not be mechanically merged, but they independently establish that serialized request bytes matter in ways that token counts alone do not capture.
2. Image-heavy sessions becoming slow, stuck, or repeatedly reconnecting
These issues are less direct about the exact request-byte threshold, but independently show the same workload class becoming unreliable after image history accumulates.
#20805 — Image-heavy chats repeatedly reconnect and become very slow
#33094 — Codex Desktop repeatedly disconnects when analyzing images
#32868 — WebSocket disconnects before response.completed after viewing multiple images in a long CLI turn
#33018 — Related unusually slow image-input turns.
#32555 — Image-heavy thread stays in Thinking and later reports Broken pipe
#33021 — Image-generation results write multi-million-character payloads into project-thread events and the thread stalls
#40249 — Image Base64 bypasses read_thread output limits and repeatedly stalls recovery tasks
#18629 — Desktop threads can be poisoned by inline Base64 tool images
These are useful impact/corroboration reports, but I am not using them as proof of the exact 63.8 MB causal chain in #43015.
3. Failed-compaction / poisoned-session recovery
#31579 — Thread gets stuck after failed auto-compact; app-server keeps stale in-memory history until unload
This is particularly relevant to the requested recovery story.
Even after persisted history was repaired, the app-server continued using stale broken in-memory history until the session was unloaded/reloaded.
That illustrates why users need a supported recovery procedure rather than manual JSONL/SQLite modification.
4. Compaction retaining or duplicating raw image/media payloads
These primarily concern Stage C rather than the zero-compaction Stage-B condition demonstrated in #43015.
They are nevertheless important because they show that the same representation problem continues after compaction unless explicitly bounded.
#24388 — Remote compaction deadlocks when input_image payloads remain in compacted replacement history
#33493 — Local compaction v2 retains unbounded input_image payloads
#38835 — Remote compaction v2 retains raw media and can trigger repeated auto-compaction
#36446 — Context Size / retained images after repeated compaction
#23257 — Desktop compaction repeatedly embeds full image Base64 in compacted checkpoints
#31040 — macOS compaction checkpoints re-embed screenshots until rollout reaches multiple GB
#34863 — app-server reaches 27 GB footprint after compacted records repeatedly retain inline PNG data URLs
#39013 — repeated compacted image snapshots grow rollout to 16.9 GB and app-server to 19.5 GB
#40323 — Windows automatic compaction repeatedly embeds inline images, growing rollout beyond 16 GiB
#37346 — Runaway inline image duplication during context compaction creates 20+ GB rollouts
#35458 — screenshots re-persisted on every compaction and inherited by subagent forks; session storage reached ~165 GiB
#33735 — Windows Codex App session JSONL files grow to ~24 GB from repeated inline image data
#41806 — ~/.codex grew to 42 GB; compaction re-embeds replacement_history and archived sessions accumulate
#40111 — One rollout JSONL grew to approximately 98 GB from inline Base64 PNG payloads
#40175 — Browser tool auto-attaches screenshots to Code Mode results, permanently inflating history
The existence of Stage-C mitigations does not eliminate the Stage-B problem.
A session may accumulate tens of megabytes of active image history before the first successful compaction, as #43015 demonstrates.
5. Fork / resume / subagent amplification
Once heavyweight inline history exists, several independent reports show that resume/fork/subagent paths can multiply or reconstruct it.
#34268 — Multi-agent V2 full-history forks duplicate historical compaction snapshots and inline images
#33235 — Image-heavy multi-agent task replays inherited image context, causing very large traffic/token/storage amplification
#33796 — Windows Desktop multiple 1–2 GB rollout sessions correlate with ~71 Mbps upstream bursts during resume
#24948 — Session logs grow to hundreds of MB / multiple GB from repeated compaction history and raw tool output
#24676 — Windows Desktop hangs when opening an image-heavy rollout
#22004 — Related oversized rollout / Desktop process-limit behavior.
#21948 — Large active session degrading the wider Desktop process.
#22603 — Related generated-image payload persistence.
#32533 — Responses Lite full-history resend after request-property change strands a large session until compaction
The key architectural point is that incremental continuation can temporarily hide the cost of a large history. A reconnect, resume, reuse mismatch, fork, or HTTP fallback can then require a full-history request and suddenly expose the serialized-byte problem.
6. Additional linked persistence / compaction / storage reports
The closest reports above themselves reference a wider family of related issues.
For completeness, those secondary references include:
I am listing these as secondary related references only. They should not be assumed to reproduce the specific Stage-B 63.8 MB condition in #43015.
7. Adjacent context-accounting issues
#9601 — Backtrack rewind sets context remaining to 0% and triggers auto-compaction
Relevant because one affected estimation path serializes history and can badly misrepresent structured/image-heavy state.
#11072 — Context compaction triggered after screenshot-producing tool calls in a fresh session
Relevant to image/tool-output interaction with context management.
These are supporting context-management references rather than direct request-size reproductions.
8. Separate but interacting WebSocket-liveness issue
This is deliberately a separate issue.
Its deterministic localhost reproduction is image-free and only approximately 42 KB, so large image history is not necessary to reproduce the #43022 liveness bug.
However, the two classes of defect can plausibly amplify each other in production:
This is a system-level amplification model, not a claim that every observed timeout followed this exact chain.
9. Diagnostic bridge
This can be correlated with the separately supplied diagnostic material if useful.
Why a per-image limit or token-only compaction is not sufficient
The measured #43015 history contained:
Therefore:
A workload containing many individually acceptable images can still produce a pathological aggregate request.
The relevant invariant needs to cover the whole active model-visible history, not only each image independently and not only retained images after compaction.
Conceptually:
The exact value and policy for
B_maxis an implementation/product decision, but some aggregate byte-denominated lifecycle invariant is needed if downstream transports/endpoints have byte-denominated limits or pathological processing costs.Requested maintainer action
I would appreciate triage specifically across the entire lifecycle rather than treating this only as a compaction-retention issue.
In particular:
The purpose of this comment is to make the existing independent evidence discoverable in one place while preserving the evidence boundaries of each report.
The central additional result from #43015 is still the zero-compaction observation:
That is why Stage-B aggregate byte management appears to remain a necessary part of the fix, even if later compaction/image-budget paths are also improved.
FengYeeLx commentedon Sep 8, 2026
Source-level clarification: model-context accounting and serialized-request bytes are separate resource dimensions
I found one additional source-level detail on current
mainthat appears to make the architectural boundary in this report more precise.This is not a new runtime reproduction, and it does not change the evidence boundaries in the original report. In particular, I am not claiming a universal server-side request-size limit, nor that every transport stall observed in the affected session was caused by payload size.
The new point is narrower:
That distinction appears directly relevant to the zero-compaction, 63.8 MB active-history condition measured in this issue.
1. Current history accounting explicitly separates image payload bytes from model-visible cost
Checked on current
maincommit:ce254df05a3162a93d8f3357ff4dd86582c534b7Relevant source:
https://github.com/openai/codex/blob/ce254df05a3162a93d8f3357ff4dd86582c534b7/codex-rs/core/src/context_manager/history.rs
In
estimate_response_item_model_visible_bytes, Codex first obtains the serialized JSON size of an item, but then separately measures inline image payloads and replaces their actual Base64 payload contribution with a modality-specific estimate.The core operation is effectively:
The source comment explicitly describes this as replacing raw Base64 payload bytes with per-modality estimates.
For ordinary resized image inputs, the current estimator uses:
and later converts the estimated model-visible byte count to an approximate token count.
For
detail: "original", the estimator instead decodes the image dimensions and estimates the model-visible cost from 32 px patches, capped at 10,000 patches.The important point is that this is not necessarily incorrect token accounting.
For model context purposes, a multi-megabyte PNG should not necessarily cost the model the same number of tokens as several megabytes of ordinary text. The model sees an image modality, not a Base64 character stream in the ordinary text-token sense.
The problem exposed by this issue is therefore a different resource constraint.
There are at least two independent quantities:
A request can satisfy:
while
B_serializedcontinues growing independently to an operationally problematic size.That is exactly the kind of divergence observed here.
2. Why this matters for the measured #43015 workload
The affected history measured in this report contained:
The HTTP request layer recorded:
The important observation is therefore not merely:
A more precise statement appears to be:
For this workload, the active history could therefore remain acceptable under the model-context accounting while containing more than 60 MB of serialized inline image data.
This also explains why prompt caching does not eliminate the problem.
Caching may reduce repeated model computation associated with unchanged context, but it does not by itself remove the inline Base64 strings from a full serialized request when that request must be reconstructed and submitted again.
3. The missing invariant appears to be aggregate and byte-denominated
The architectural safeguard I am asking about is therefore not:
and not merely:
Instead, there appears to be a missing independent invariant for the model-visible active history.
Conceptually:
where
B_budgetis an implementation-defined operational budget, not a server limit that I am claiming to know.The byte budget also does not necessarily need to mean "hard reject the user request."
It could instead be a preflight trigger for one or more lifecycle actions before constructing or retrying an excessively large full-history request, for example:
The exact policy is an implementation decision.
The important property is that the aggregate byte dimension needs to be bounded independently of the model-token dimension.
4. A per-image preparation budget does not establish an aggregate history budget
Current
mainalso contains the under-developmentUnifiedImageBudgetfeature:Relevant source:
https://github.com/openai/codex/blob/ce254df05a3162a93d8f3357ff4dd86582c534b7/codex-rs/core/src/image_preparation.rs
The current preparation path walks messages and tool outputs, finds individual
InputImageitems, and callsprepare_imagefor each image.prepare_imagethen applies an image preparation mode, loads/resizes the individual data URL, and replaces that image URL with the newly prepared data URL.That can be a useful mitigation because reducing each image can substantially reduce the eventual aggregate request.
However, a per-image invariant such as:
does not imply:
For example, even if every retained image were reduced to 1 MiB:
The exact numbers are illustrative only; the mathematical distinction is the relevant part.
The failure reported here already demonstrates the same structure at a smaller count: none of the 38 image occurrences individually exceeded 10 MiB, yet their aggregate contribution was approximately 61.28 MB of data-URL characters.
So
UnifiedImageBudgetmay reduce the magnitude of the problem, but from the inspected source I do not see it establishing an aggregate serialized-byte invariant across all images retained in ordinary active history.If that feature is intended to provide such a guarantee elsewhere in the pipeline, clarification would be useful.
5. The existing large-input sanity guard is also not an aggregate transport budget
The current image utility defines:
Relevant source:
https://github.com/openai/codex/blob/ce254df05a3162a93d8f3357ff4dd86582c534b7/codex-rs/utils/image/src/lib.rs
However, the source explicitly describes this as a high sanity guard against pathological individual image inputs, not as a protocol requirement or target upload size.
I therefore do not interpret this value as:
It operates at a different layer and on an individual input representation.
The issue here is the aggregate serialized state accumulated across many individually valid history items.
6. The HTTP request layer already measures the relevant byte quantities
The HTTP request implementation already records:
Relevant source:
https://github.com/openai/codex/blob/ce254df05a3162a93d8f3357ff4dd86582c534b7/codex-rs/http-client/src/request.rs
Those are the same measurements that exposed the approximately:
request in this report.
So the byte dimension is already observable at request construction time.
What I have not found in the inspected ordinary parent-model path is an equivalent aggregate lifecycle decision such as:
I am intentionally limiting that statement to the inspected public paths rather than claiming that no such protection exists anywhere internally or server-side.
7. Why the safeguard is needed before compaction, not only inside compaction
This report's distinguishing condition remains:
at the measured failure snapshot.
That creates an important lifecycle distinction:
Existing compaction-time image safeguards primarily operate at Stage C or while constructing a compaction result.
But #43015 demonstrates that Stage B itself can already become very large.
Therefore:
does not imply:
and:
does not guarantee that the next active working window cannot accumulate the same condition again.
The recent independent evidence in #41338 is consistent with this lifecycle distinction: an earlier compaction successfully reduced the retained history, subsequent visual work accumulated dozens of images again, and the next compaction request itself became very large.
Related:
#41338
8. Full-history transitions are where this becomes especially important
I am not claiming that every normal WebSocket continuation necessarily resends the complete 63.8 MB active history.
Codex can use incremental Responses/WebSocket state when the previous-response relationship and history prefix remain reusable.
However, the aggregate active history still matters because several lifecycle transitions can require a much larger reconstruction, including cases such as:
The exact request shape depends on the path and state.
The architectural concern is therefore:
That is why the invariant needs to apply to the retained active state itself, rather than only reacting after a particular transport rejects a request.
9. Retrying an unchanged large request is a separate amplification problem
The original report and related evidence also show repeated attempts with nearly unchanged request sizes.
If a request fails for a reason plausibly related to request ingestion or transport handling, blindly reconstructing and retrying effectively the same large payload does not reduce the condition that may have contributed to the failure.
A more robust recovery path would ideally be able to distinguish:
from:
and, when appropriate, modify the active representation before another expensive full submission.
This is especially relevant when a compaction attempt itself requires carrying the history that needs to be reduced.
Otherwise the recovery mechanism can become dependent on successfully transmitting the pathological state it is supposed to repair.
10. There is already an aggregate image-byte-budget precedent elsewhere in Codex
For design precedent only, not as a claim that #43015 is already fixed:
Merged PR #43601 moved Guardian transcript image selection into shared context sections while preserving an aggregate limit of:
with coverage for:
PR:
#43601
This is a different subsystem and does not bound ordinary parent-model active history.
I mention it only because it demonstrates that an aggregate media-byte budget plus eviction/omission accounting is already an established design pattern within the Codex codebase.
A conceptually similar invariant at the ordinary model-history boundary appears directly relevant to the failure mode demonstrated here.
11. What I believe the source now establishes, and what it still does not establish
Established by the source plus the measurements in this report
The current client has two materially different resource dimensions:
and:
Inline image Base64 payload bytes are intentionally discounted in the former while remaining physically present in the latter when full history is serialized.
Therefore, a token/context budget alone cannot mathematically impose a bound on serialized request bytes.
The measured #43015 workload demonstrates that this distinction is not merely theoretical: ordinary active history reached approximately 63.8 MB before compression before any compaction had occurred.
Not established
This does not establish:
UnifiedImageBudgetis ineffective;The narrower claim is that an independent aggregate serialized-byte lifecycle safeguard still appears necessary.
12. More specific maintainer questions
With the source distinction above, I would particularly appreciate clarification on the following architectural questions:
Is there currently an intended aggregate serialized-byte budget for ordinary parent-model active history before compaction?
If such a budget exists, where is it enforced relative to:
Is
UnifiedImageBudgetintended only to normalize individual image preparation, or is another layer expected to bound the aggregate retained media size?When a full request is already very large and a retry/fallback occurs, is there any client-side mechanism intended to reduce the retained payload before submitting essentially the same history again?
Could the already-recorded request measurements:
pre_compression_bytes;post_compression_bytes;be incorporated into preflight lifecycle decisions rather than diagnostics only?
For an already affected session, is there a supported recovery path that can locally reduce or externalize old media without requiring a successful remote compaction request and without manually editing rollout/SQLite state?
I believe answers to those questions would make it much easier to determine whether existing image-budget work already covers the Stage-B condition demonstrated here or whether a separate aggregate active-history byte safeguard is still required.
Again, this comment is intended as a source-level clarification of the existing report, not as a new claim of a fixed server-side byte threshold or a new production reproduction.
FengYeeLx commentedon Sep 9, 2026
Follow-up: new evidence shows the byte-budget problem extends across persistence and migration boundaries
A newly filed report, #44141, exposes another byte-denominated lifecycle failure that is separate from, but architecturally relevant to, this issue.
In Codex 0.153.4, the legacy-to-paginated rollout reader applies a 16 MiB per-record limit before record type is parsed. An oversized record can therefore be drained and skipped during migration. At the same time, ordinary compaction persistence can write a Compacted record containing replacement_history and guardian_history without that same per-record bound.
The #44141 reporter observed an image-containing task where later successful-compaction markers existed but corresponding full checkpoints were absent from the migrated history; the last surviving full checkpoint was approximately 15.5 MiB. The report correctly treats the resulting resume/context-overflow causal chain as a strong hypothesis rather than a completed deterministic reproduction.
This is not the same failure as the 63.8 MB active Responses request reported here. However, it strengthens the architectural point: model-token cost and serialized bytes are independent resource dimensions, and byte invariants need to remain coherent across the entire history lifecycle—not only at compaction time.
Current main still explicitly replaces raw Base64 payload bytes with per-modality estimates in history accounting:
// Replace raw base64 payload bytes with per-modality estimates.
That is reasonable for estimating model-visible cost, but it cannot by itself bound serialized request or persisted-state bytes. unified_image_budget also remains UnderDevelopment and disabled by default, while compaction_image_budget is stable and enabled by default.
The invariant I think the implementation ultimately needs is broader than a single per-image limit:
model-visible tokens <= token budget
active request bytes <= request-byte budget
state-bearing record bytes <= persistence-safe budget
resume/migration semantics == pre-migration semantics
A durable fix should therefore cover active pre-compaction history, compaction, persistence, migration, resume/fork, and retry/fallback paths without silently dropping state-bearing media or repeatedly materializing the same large inline payloads.
baibenyu commentedon Sep 11, 2026
Additional Windows desktop reproduction: WebSocket works with a local proxy, but image-heavy sessions later close and fall back to repeated large HTTP requests. A newly created session eventually reproduced the same problem.
This report was prepared by Codex from read-only inspection of my machine's desktop processes, configuration, retained client logs, and session-history structure. The measurements below are local observations, not a claim about a proven server-side size limit.
Environment
26.903.8094.0, subsequently updated to26.903.9818.0.codex-cli 0.153.4after the desktop update; I did not substitute a separately installed CLI version.gpt-6-astra, ChatGPT authentication.openai. One older session retained a customopenai_httpsprovider ID, withname = "OpenAI", the standard ChatGPT Codex endpoint,requires_openai_auth = true, andsupports_websockets = true.features.enable_request_compression = true..env, pointing to the working local HTTP proxy. Windows global proxy environment variables were not added.Proxy repair worked, but did not prevent later recurrence
After configuring
.envand restarting the desktop app, the actual desktop task usedtransport="responses_websocket"and generated responses/tool calls without HTTP fallback. A 15-minute sampling window on September 10 measured approximately 14.97 MB sent and 5.10 MB received for selected Codex desktop/backend IPv4 TCP connections, with no recorded HTTP fallback during that window.Those counters included local proxy connections, excluded other local IPC, and did not cover UDP/IPv6 or every short-connection tail. They are not VPN billing totals or a controlled before/after benchmark.
Recurrence and a natural compaction comparison
All times below are September 11, 2026, UTC+08:00.
websocket closed by server before response.completed, retries 1/5 through 5/5.falling back to HTTP.websocket closed by server before response.completed.Image counts above are structural history inspections starting from the latest compacted replacement history and appending subsequent response items; they are not wire-byte measurements. The request-byte figures are the client's
pre_compression_bytes/post_compression_bytesmetrics.Other concurrent tasks still used WebSocket, and the proxy configuration remained intact. Image-heavy request growth is strongly associated with the failures here, but the logs do not establish whether the connection closes originate from an upstream size constraint, proxy handling of large messages, or another transport issue. This also does not establish that the desktop update caused the recurrence.
Requested fixes / supported controls
supports_websocketsdoes not provide this behavior.Please link any fix PR and the desktop/backend release containing it to this issue so affected users can verify the resolution. Happy to provide additional narrowly scoped, redacted diagnostics if needed.
FengYeeLx commentedon Sep 12, 2026
Help, please help!!
@etraut-openai
majiamajiabj-boop commentedon Sep 15, 2026
Additional Windows desktop evidence: synthetic 12-image request receives close 1009 on 0.154.0-alpha.6.2
Adding a bounded reproduction and explicit close-frame evidence to this tracker, rather than another duplicate image-history issue.
Observed September 14–15, 2026: Windows x64 desktop app
26.908.4834.0, bundledcodex-cli 0.154.0-alpha.6.2, built-in OpenAI provider with normal ChatGPT authentication, modelgpt-6-astra. A local HTTP proxy / TUN was present. No modified Codex binary was used.Reproduction and controls
Twelve deterministic 640×560 RGB PNGs contribute 17,234,084 base64 bytes. Supplying them to a new, ephemeral, read-only CLI request asking only for
NETWORK_OKrepeatedly produces:The installed client retries the same rejected request and displays reconnection attempts. The twelve-image test did not complete within its 90-second bound.
unified_image_budgetdid not change this twelve-image input's prepared size, and a live twelve-image test with the flag still received 1009.These results establish an explicit size rejection for the synthetic request. They do not establish an exact universal server limit, or prove that all historical 10053/10054 errors share this cause.
Minimal synthetic input
Requires Python and Pillow:
Then, with the installed CLI already normally authenticated, in PowerShell:
The measurements above were taken with a harness enforcing a 90-second process limit. Stop the manual command if it enters repeated reconnects. No private documents are needed to reproduce this.
Why forcing HTTP is not a complete mitigation
In the affected real desktop task, retained client telemetry showed repeated requests of approximately 32 MB before zstd / 21 MB after zstd, with compression itself taking only 56–60 ms. One request connection had uploaded approximately 16.6 MB after about four minutes. The task did sometimes advance between these waits; this is not a claim of a permanent deadlock or pure upload speed inferred from total response time.
A successful compaction temporarily reduced a later request to 168,584 bytes before compression / 67,289 after, but new image outputs subsequently rebuilt large requests. Switching TLS backends in process-local controls did not establish a reliable fix. Global HTTP forcing is no longer enabled.
At official source ref
rust-v0.154.0(6b9826e3aa83b1a5947db50f4332cb9c65f1b340), the response reader discards the close frame inMessage::Close(_)and maps it to a generic stream error. This appears to explain the avoidable unchanged retries, separately from aggregate image-history growth and slow HTTP replay.Please provide an official recovery procedure for existing affected desktop tasks, clarify which release addresses aggregate request bytes and close-1009 retry handling, and indicate whether a supported setting can mitigate this without editing session JSONL/SQLite or building a custom client.
This comment contains only synthetic reproduction instructions, sanitized transport excerpts, aggregate measurements and public source references. No original images, prompts, session IDs, credentials, cookies, account identifiers, private paths or raw diagnostic bundles are included.
Marshmallow12138 commentedon Sep 22, 2026
Additional user report: repeated desktop stalls, including when trying to compact
Reporting possibly related symptoms at the affected user's explicit request:
These are user-reported symptoms. This comment does not establish that image count, networking, or the same root cause as the original issue is responsible.
Could a maintainer confirm whether this symptom pattern is covered by this issue, provide supported recovery steps that preserve existing task history, and link a fix or release if one is available?
This report intentionally includes no local logs, proxy configuration, request measurements, project content, account details, or session identifiers.
smartLanny commentedon Sep 27, 2026
New Windows desktop reproduction on 0.158.0-alpha.2.1: six tool images grow requests from 0.25 MB to 23.85 MB, with repeated 6–7 minute waits
Adding fresh measurements to this existing tracker rather than opening a duplicate. The affected user explicitly requested this report.
In the same active turn, requests took roughly 3–6 seconds before image inspection. After three tool images, serialized requests grew to 13.66 MB after zstd; after three more crops, they grew to 23.85 MB. Subsequent small coordination steps continued to send requests of that size and waited approximately 397–429 seconds before HTTP response headers.
Environment
26.924.2738.0.cli_version = 0.158.0-alpha.2.1, originator Codex Desktop.gpt-6-astra,ultra, service tierdefault.responses_http; zstd request compression was active.feature.compaction_image_budget=true.model_context_window,model_auto_compact_token_limit, ormodel_auto_compact_token_limit_scope. This is not a claim that every other setting is default.Before/after in one turn
These are application-recorded serialized request sizes. The elapsed time is from the request-compression log entry to the HTTP response-header log entry, not a pure upload or model-inference measurement. Every row below eventually returned HTTP 200.
The tool calls immediately preceding the 20:14 and 20:21 requests completed in about 247 ms and 182 ms. The long intervals were therefore in the next model-request stage, not those tools.
Image accounting and compaction
Read-only structural inspection found six new inline PNG data URLs returned through
functions.exec/view_image:Total: 31,625,980 data-URL characters, closely accounting for the approximately 32.34-MB request JSON. The first three images had already been resized to 2048 pixels wide; merely resizing full screenshots to that width did not keep aggregate bytes small.
The latest completed compaction before these images was at 17:25:45. These were new images added afterward. In a later affected sample, runtime telemetry reported
auto_compact_scope_tokens=175617, belowauto_compact_scope_limit=244800, withfull_context_window_limit=258400. Thus a substantial byte payload accumulated while the token threshold had not been reached, despite the image-budget feature flag.Separate preceding occurrence
Another session on September 26 produced approximately 61.4 MB before / 45.7 MB after zstd and logged HTTP 408 with
{"detail":"Request body read timed out"}, followed by automatic retries. Selected timeout times were 13:41:48, 14:03:08, 14:33:39, 14:48:54, and 15:19:24 UTC. Later similarly sized requests sometimes succeeded much faster, so payload size alone does not explain all timing variance.Scope and requested investigation
This is an observed real-workflow recurrence, not a newly executed clean-room reproduction or a source-level proof of a specific defect. No packet capture, controlled network/proxy comparison, or server trace was collected for these occurrences. The evidence cannot partition the multi-minute interval between upload, network/proxy behavior, and backend waiting; it does not establish a universal size limit or a permanent deadlock.
The actionable pattern is aggregate tool-image byte growth, persistent large HTTP request bodies after image inspection, and severe stalls/timeouts. Please investigate:
Related: #45109. This report adds a newer desktop/runtime observation, an immediate same-turn before/after, six resized/cropped PNGs, and repeated successful requests that each still take 6–7 minutes.
Only aggregate measurements and selected non-secret fields are included. No screenshots, prompts, project content, session IDs, private paths, credentials, cookies, raw logs, or diagnostic databases are attached.
xiao-do-do commentedon Oct 2, 2026
Severe performance and bandwidth issue: repeated historical-image uploads after
connection fallback make Codex extremely slow during multi-turn image generation.
Environment: macOS, Codex desktop app.
Steps to reproduce:
Generate and edit images across multiple turns in the same conversation.
The app begins showing “Reconnecting 1/5” through “5/5.”
After the retries, the connection falls back to HTTP/SSE.
Continuing the same conversation results in repeated uploads of large amounts of
historical image data. Even simple text follow-ups become extremely slow.
Actual impact:
While using this workflow, my data usage exceeded 100 GB in a single day. The repeated
transfers consume substantial bandwidth and significantly increase the waiting time for
each conversation turn, severely disrupting ordinary conversation and iterative design
work. This is a serious performance and usability issue.
Related GitHub reports:
#38846
#44715
#33760
#46761
A user in #38846 captured WebSocket close code 1009 (“message too big”). I have not
confirmed the close code in my own session. Please use the attached diagnostic logs to
investigate the relationship between growing image history, WebSocket disconnections,
HTTP/SSE fallback, and repeated image uploads.
GrinZero commentedon Oct 8, 2026
This issue is highly critical and should be addressed as soon as possible.
majiamajiabj-boop commentedon Oct 9, 2026
Recurrence on Windows desktop 26.1002.7124.0: 48 historical images carried into a simple follow-up, ~23.2 MB compressed requests
Follow-up to my earlier Windows image-history report. This was observed on October 8–9, 2026 (times below are UTC+8), using GPT-6 Astra with high reasoning. Fast mode was actually enabled:
service_tier=priorityand runtimefeature.fast_mode=true.A presentation/document task viewed many local preview images. A subsequent simple email task in the same conversation inherited those images and continued sending large model requests even for text/file bookkeeping steps.
Measured request sizes and timings
These intervals are client-observed request waits, not measurements of model reasoning time or pure upload time.
Important confounders, separated from the image issue
Requested improvement
Please bound aggregate retained image/request bytes, and provide a supported recovery path for existing image-heavy conversations. Compaction briefly reduced request size, but repeated tool-preview images grew it again and made an unrelated follow-up repeatedly pay the full transport cost. Avoiding repeated oversized requests would materially improve reliability even when the network route is imperfect.
This comment contains aggregate measurements only; no email addresses, document contents, image data, credentials or private attachment payloads are included.
FengYeeLx commentedon Oct 9, 2026
OpenAI is a massive scam and criminal organization, and I've had enough of their attitude towards the community. I sincerely hope that everyone, including all of OpenAI's customers, will immediately abandon this foolish company and switch to Claude.
If OpenAI is actually using its own Codex, how could this issue have gone unnoticed for so long? People seem unwilling to accept any kind of community feedback, and now they're ignoring the issues raised by the community. However, if Codex is a paid software, and I'm paying $200 a month to this group, I expect someone to take legal action against them.
Let’s be brutally clear, again, because apparently the first thousand warnings weren’t enough: a $200-a-month subscription is not a license to ignore your users, gaslight your community, and ship broken promises behind a paywall. If Codex is supposedly good enough to build OpenAI’s own products, then why does it fail so spectacularly in public? Either it isn’t being used, it isn’t good enough, or the people running the show are too arrogant to listen. Every one of those answers is damning. Feedback gets buried, bug reports get stonewalled, critics get treated like nuisances, and paying customers are expected to shut up and feel grateful. That isn’t a platform; that’s a toll booth with a god complex.
And don’t give me the “we’re shipping fast” excuse. Shipping fast into a wall isn’t innovation; it’s negligence with a launch party. If they can’t even handle the problems their own community reports, then either the product is a Potemkin demo or the company is too busy counting subscriptions to care. You can’t charge premium prices and act like a broke startup that owes nobody an explanation. That’s not lean. That’s parasitic.
So here’s the only sane response: cancel. Migrate to Claude. Stop funding the machine that treats you like an unpaid QA tester and then bills you for the privilege. And if OpenAI really is charging $200 a month while ignoring paying customers, I hope the chargebacks, the lawsuits, and the public humiliation arrive faster than their next half-baked announcement. Maybe then they’ll learn that contempt is not a business model—and that a community you refuse to hear is a community you deserve to lose.
1. The $200/Month Contradiction: Premium Price, Dollar-Store Accountability
Let’s start with the most insulting part: the price. Two hundred dollars a month. That is not a casual subscription. That is not “tips for the developers.” That is rent. That is a car payment. That is a serious line item for freelancers, students, researchers, startups, and small teams who actually have to justify every dollar they spend. And what do they get in return? A product that breaks, an API that changes under their feet, a support system that feels like shouting into a void, and a community relations strategy that can be summed up as “we’ll do whatever we want, and you’ll like it.”
If you charge enterprise prices, you owe enterprise accountability. If you charge luxury prices, you owe luxury reliability. If you charge $200 a month and then act like anyone who complains is an enemy of progress, you are not a serious company. You are a subscription trap with a research paper. You are a billing system with a chatbot attached. You are a company that has confused “we have users” with “we have hostages.”
And the worst part is the arrogance. The attitude. The sneering, tech-bro, “we’re saving humanity” nonsense that oozes out of every carefully staged announcement. OpenAI talks about safety, alignment, and the future of civilization while treating its own paying customers like inconvenient noise. It lectures the world about responsible deployment while ignoring basic customer service. It begs regulators to trust it while treating community feedback like a mosquito to be swatted away. That is not leadership. That is a cult of personality with a legal department.
If you are charging people $200 a month, you do not get to ignore them. You do not get to bury their bug reports. You do not get to pretend that every criticism is bad faith. You do not get to hide behind “we’re working on it” for months while cashing the checks. That is not a product roadmap. That is a grift with a GitHub repository.
2. The Codex Hypocrisy: If It’s Good Enough for OpenAI, Why Is It Garbage for Everyone Else?
The Codex issue is the perfect symbol of everything wrong with OpenAI. The company claims to be building world-class coding tools. It markets them as transformative. It charges for them. It uses them, allegedly, in its own workflows. And yet, somehow, the public-facing experience is a mess. Bugs linger. Regressions pile up. Users report the same problems over and over, and nothing changes. If Codex is actually being used internally, then either OpenAI’s internal standards are laughably low, or the public is getting a deliberately degraded version. If it is not being used internally, then the marketing is a lie. Either way, the customer loses.
Think about that. A company that wants to sell you the future of software development cannot even maintain basic quality control on its own coding product. A company that claims to be at the forefront of AI cannot respond to community bug reports without acting like it’s doing you a favor. A company that wants to be trusted with the future of work cannot be trusted to fix a broken feature that paying customers rely on every single day.
And the excuses are always the same. “It’s a research preview.” “It’s evolving.” “We’re shipping fast.” “You don’t understand the complexity.” No. You don’t understand the deal. The deal is simple: you take money, you provide a working product, and you listen when it breaks. If you can’t do that, get out of the subscription business. Go back to writing blog posts about how misunderstood you are. Go back to publishing papers that nobody can reproduce. Go back to giving TED talks about the future while the present falls apart.
If Codex is so revolutionary, why does it feel like a beta test that escaped the lab? If it’s so powerful, why do users have to fight it every step of the way? If it’s so essential, why does the community keep saying the same thing: it’s not ready, it’s not reliable, and the company doesn’t care? OpenAI has mastered the art of selling the idea of a product while delivering the reality of a prototype. That is not innovation. That is fraud with a branding budget.
3. Community Feedback: The Sound of a Company Covering Its Ears
OpenAI’s treatment of community feedback is not a bug. It is a feature. The company has built a culture where criticism is tolerated only if it is polite, vague, and ultimately ignored. Speak up too loudly? You’re a hater. Point out a regression? You’re not grateful. Ask for basic accountability? You’re attacking progress. Demand that a $200 subscription work? You’re being unreasonable. This is not a community relationship. This is an abusive relationship with a terms-of-service page.
The community has been screaming for months. Developers have filed issues. Users have posted detailed bug reports. Researchers have pointed out flaws. Competitors have shipped better alternatives. And OpenAI’s response has been a mix of silence, corporate platitudes, and the occasional condescending blog post that says nothing and promises even less. They treat feedback like a public relations problem instead of an engineering mandate. They treat their most engaged users like free labor. They treat criticism like betrayal.
And then they wonder why people are angry. They wonder why trust is collapsing. They wonder why every new announcement is met with skepticism instead of excitement. The answer is simple: you cannot repeatedly ignore people and then expect them to cheer for you. You cannot gaslight your community and then act surprised when they leave. You cannot charge premium prices and then behave like a company that has never met a customer before. OpenAI’s community strategy is not a strategy. It is a tantrum with a marketing department.
The worst part is that this is not new. This is a pattern. Every time there is a problem, the company circles the wagons. Every time users complain, the defenders appear to tell them they are entitled. Every time someone demands accountability, the conversation shifts to how amazing the future will be. It is a classic bait-and-switch: promise the world, deliver a demo, and shame anyone who notices the gap. That is not a community. That is a captive audience.
4. The Cult of OpenAI: Safety Theater, Hype Cycles, and the Arrogance of Mission
OpenAI does not behave like a company. It behaves like a movement. It speaks in prophecies. It talks about saving humanity. It warns about existential risk while simultaneously racing to deploy products that it cannot adequately support. It hires philosophers to talk about ethics while its customer support is a black hole. It publishes safety frameworks while ignoring the safety of its own users’ workflows. It is a church of AI, and the congregation is expected to tithe $200 a month.
This is not a company that listens. This is a company that preaches. It preaches about responsible AI while releasing models with known flaws. It preaches about transparency while hiding behind vague blog posts. It preaches about alignment while misaligning its incentives with its customers. It preaches about the future while failing the present. And when people push back, the response is always the same: “You don’t understand the mission.” No. We understand the mission. The mission is to make money, capture the market, and crush criticism. The mission is to be the only game in town. The mission is to make everyone dependent on a company that treats them like a nuisance.
The safety theater is especially insulting. OpenAI loves to talk about how dangerous AI could be. It loves to warn about misuse. It loves to position itself as the responsible adult in the room. But a responsible adult does not charge $200 a month for a broken product. A responsible adult does not ignore bug reports. A responsible adult does not gaslight its community. A responsible adult does not use safety as a shield while behaving like a reckless monopolist. If OpenAI were serious about safety, it would start by being honest with its customers. It would start by fixing its products. It would start by listening. It does none of that.
Instead, it performs. It performs concern. It performs caution. It performs humility. And then it ships another half-baked feature, raises prices, and tells everyone to be patient. This is not safety. This is theater. This is a company using the language of ethics to avoid the obligations of business. It is a company that wants all the power of a monopoly and none of the responsibility of a service provider.
5. The Legal Reckoning: Chargebacks, Class Actions, and Consumer Protection
If OpenAI is charging $200 a month and failing to deliver, then the legal system should be involved. Not because lawsuits are fun, but because they are the only language that corporations like this understand. Consumer protection laws exist for a reason. False advertising laws exist for a reason. Contract law exists for a reason. If you promise a service and fail to provide it, you are not just a bad company. You are a legal liability.
Paying customers should file chargebacks. They should document every failure. They should organize. They should contact consumer protection agencies. They should talk to attorneys. They should explore class action possibilities. They should demand refunds. They should not quietly cancel and move on while OpenAI keeps the money and the market share. They should make noise. They should make it expensive. They should make it embarrassing.
And regulators should pay attention. A company that markets itself as the future of AI, charges premium prices, and then ignores basic consumer protections is not above the law. It is a test case. It is an example of what happens when tech companies believe that their mission excuses their misconduct. The FTC, the EU, state attorneys general, and consumer advocates should all be asking the same question: if this were any other industry, how long would this behavior be tolerated? If a telecom company charged $200 a month and ignored outages, there would be hearings. If a bank charged fees and failed to provide services, there would be fines. If a software company sold a broken product and mocked its customers, there would be lawsuits. OpenAI should not get a pass because it says “AI” a lot.
The $200-a-month price point is not just a business decision. It is a declaration. It says: we believe our product is worth this much. If that is true, then the product must meet that standard. If it does not, then the price is not a price. It is a extraction. It is a toll. It is a tax on people who have no better option—or who thought they didn’t. And when you tax people without providing value, you are not a company. You are a racket. You are a protection scheme. You are a parasite wearing a hoodie.
6. Claude and the Exit Strategy: Stop Feeding the Beast
The only rational response is to leave. Cancel the subscription. Delete the API keys. Migrate the workflows. Move to Claude. Not because Claude is perfect, but because OpenAI has forfeited the right to your money. Every month you stay is a vote of confidence. Every dollar you pay is a signal that their behavior is acceptable. Every bug you tolerate is a message that you will tolerate more. Stop sending that message.
Switching is not just about features. It is about values. It is about refusing to be treated like an idiot. It is about refusing to fund a company that ignores you. It is about refusing to be part of a cult that mistakes arrogance for excellence. Claude may not have the same hype. Claude may not have the same marketing machine. But Claude has something OpenAI has lost: the ability to listen. The ability to improve. The ability to treat users like partners instead of marks.
And do not fall for the sunk-cost fallacy. You do not owe OpenAI loyalty because you have used it for years. You do not owe them patience because they were first. You do not owe them another month because maybe, just maybe, they will fix things. They have had years. They have had billions. They have had every advantage. And they still treat paying customers like an afterthought. That is not a temporary problem. That is a structural rot. You cannot fix a company that does not believe it needs fixing.
So cancel. Tell your friends. Tell your team. Tell your company. Post about it. Write about it. Make it clear that the era of OpenAI getting a free pass is over. They want to charge premium prices? Fine. Then they can face premium scrutiny. They want to be the dominant AI company? Fine. Then they can be the dominant example of what happens when you betray your community. They want to be the future? Fine. Then they can watch that future happen without you.
7. The Developer Betrayal: APIs, Deprecations, and the Disposable Community
Developers built OpenAI. Not the executives. Not the investors. Not the PR team. Developers built the ecosystem. They wrote the wrappers. They made the tutorials. They filed the bugs. They created the tools. They evangelized the platform. They turned a research lab into a business. And how does OpenAI repay them? With breaking changes. With deprecations. With rate limits that appear out of nowhere. With pricing changes that destroy business models overnight. With a support system that treats developers like a cost center instead of a community.
OpenAI loves to talk about its developer ecosystem. It loves to host hackathons. It loves to showcase startups. It loves to tweet about how amazing its community is. But when developers need stability, they get chaos. When they need documentation, they get vague blog posts. When they need communication, they get silence. When they need fairness, they get arbitrary enforcement. It is a relationship built on convenience, and when developers are no longer convenient, they are discarded.
The API is not a toy. It is infrastructure. People build businesses on it. People feed their families with it. People make promises to their own customers based on it. And OpenAI treats it like a beta feature that can be yanked at any moment. That is not just irresponsible. It is cruel. It is a display of power. It is a reminder that in OpenAI’s world, you are not a partner. You are a tenant. You are a renter. You are a line item. And when the rent goes up, you can either pay or leave.
Well, developers are leaving. They are moving to open-source models. They are moving to Claude. They are moving to anything that treats them like adults. And OpenAI can keep its hackathons and its hype. It can keep its stage. It can keep its applause. But it cannot keep the people who actually build the future. Because those people have long memories. Those people know who abandoned them. Those people will not forget.
8. The Media Enablers: Sycophants, Benchmarks, and the Hype Machine
OpenAI’s behavior would not be possible without a media ecosystem that treats every announcement like a moon landing. Every demo is “stunning.” Every model is “revolutionary.” Every blog post is “a major step forward.” The benchmarks are gamed. The comparisons are cherry-picked. The failures are buried. The critics are dismissed. And the public is left with a distorted picture of a company that is somehow both too big to fail and too fragile to criticize.
This is not journalism. This is cheerleading. This is access reporting. This is a symbiotic relationship between a company that craves attention and a media that craves clicks. OpenAI says jump, and the tech press asks how high. OpenAI says “safety,” and the press writes hagiographies. OpenAI says “we’re listening,” and the press prints it without checking whether it’s true. It is a feedback loop of nonsense, and the people who suffer are the users who believed the hype.
And the benchmarks? Please. Anyone who has ever used these models knows that benchmark scores are a game. They are marketing tools. They are not measures of real-world usefulness. They are not measures of reliability. They are not measures of customer support. They are not measures of whether the company will ignore you when you have a problem. OpenAI can top every leaderboard and still be a terrible company to rely on. And that is exactly what has happened.
The media needs to wake up. The tech press needs to stop being a press release distribution service. The analysts need to stop pretending that market share equals quality. The influencers need to stop shilling for free credits. The community needs to stop celebrating every incremental update like it’s a cure for cancer. OpenAI is not a god. It is a company. And companies are supposed to serve their customers. When they don’t, they deserve to be criticized. Loudly. Repeatedly. Until they change or collapse.
9. The Arrogance of the “We Know Better” Culture
OpenAI has a culture problem. It is not just the products. It is not just the pricing. It is not just the support. It is the attitude. It is the belief that the people running the company are smarter than everyone else. It is the belief that criticism is ignorance. It is the belief that the mission justifies the mistreatment. It is the belief that users are lucky to be allowed in the room. This is not confidence. This is hubris. This is the kind of arrogance that precedes collapse.
You see it in the way they communicate. The vague promises. The condescending tone. The refusal to admit mistakes. The inability to say “we screwed up.” The way they announce changes as if they are gifts. The way they treat feedback as an attack. The way they treat competitors as enemies. The way they treat regulators as obstacles. The way they treat the public as children who need to be managed. It is a company that has forgotten who pays the bills. It is a company that has forgotten that trust is earned, not demanded.
And the saddest part is that it did not have to be this way. OpenAI could have been great. It could have been transparent. It could have been responsive. It could have been a company that treated users as partners. It could have been a company that fixed bugs, honored commitments, and respected its community. But it chose arrogance. It chose hype. It chose extraction. It chose the path of every company that believes its own press releases. And now it is paying the price. The community is angry. The developers are leaving. The trust is gone. And no amount of safety theater or mission statements will bring it back.
10. The Call to Action: Cancel, Sue, Migrate, Repeat
So what do we do? We stop pretending. We stop waiting. We stop hoping that OpenAI will suddenly become a good company. We cancel our subscriptions. We demand refunds. We file chargebacks. We document failures. We share our stories. We organize. We support competitors. We move to Claude. We build alternatives. We make it clear that we will not be ignored.
We also hold them accountable. We contact regulators. We support lawsuits. We demand investigations. We use our voices. We use our wallets. We use our platforms. We make it expensive for OpenAI to treat customers like garbage. We make it embarrassing. We make it unavoidable. We do not let them hide behind their brand. We do not let them hide behind their mission. We do not let them hide behind their lawyers. We make them answer for their behavior.
And we remember. We remember every ignored bug report. We remember every broken promise. We remember every condescending blog post. We remember every time they treated us like we were the problem. We remember, and we act. Because the only thing a company like OpenAI understands is pressure. The only thing it respects is power. The only thing it fears is losing money and reputation. So we take both.
Cancel your subscription today. Migrate to Claude. Tell everyone you know. Write about it. Post about it. Make it trend. Make it hurt. Make it clear that the community is not a resource to be mined. It is a force to be reckoned with. OpenAI has spent years treating its users like an afterthought. Now it can learn what happens when the afterthought walks away.
11. The Final Indictment: A Company That Deserves to Lose
OpenAI is not a victim. It is not a misunderstood genius. It is not a noble mission struggling against unfair criticism. It is a company that made choices. It chose to charge premium prices. It chose to ignore feedback. It chose to gaslight its community. It chose to prioritize hype over reliability. It chose to treat its customers with contempt. And now it can live with the consequences.
If you are still paying OpenAI $200 a month, ask yourself why. What are you getting? A product that breaks? A support system that ignores you? A company that treats you like an inconvenience? A community that is constantly told to shut up and be grateful? Is that worth $200? Is that worth your time? Is that worth your trust? No. It is not. You deserve better. You deserve a company that listens. You deserve a company that fixes bugs. You deserve a company that respects you. You deserve Claude.
So leave. Cancel. Migrate. Sue if you have to. Complain if you must. But do not stay. Do not keep funding the machine that despises you. Do not keep giving your money to a company that has made it clear it does not care. Do not keep pretending that things will get better. They will not. Not until OpenAI faces real consequences. Not until the money stops. Not until the reputation burns. Not until the community says enough.
OpenAI is a massive scam and criminal organization? Maybe a court will decide the legal labels. But one thing is certain: it is a company that has betrayed its users, ignored its community, and charged a fortune for the privilege. It is a company that has confused arrogance with excellence. It is a company that has mistaken patience for weakness. And it is a company that deserves to lose every customer who has been treated like an afterthought.
So let it lose. Cancel today. Move to Claude. Tell the world. And never look back. Because the future belongs to companies that respect their users—not to companies that treat them like a subscription to be harvested and discarded. OpenAI had its chance. It blew it. Now it can watch the exodus begin. And it can have no one to blame but itself.
@ae-openai @bc-openai @by-openai @jn-openai @open-matt @ase-openai @nf-openai @gverma-openai @angad-openai @miz-openai @maxb-openai @cam-openai @charlie-openai @charlesdu-openai @wolf-openai @frantic-openai
Fuck OpenAI.
Fuck this $200-a-month scam.
Fuck the gaslighting.
Fuck the ignored bug reports.
Fuck the buried feedback.
Fuck the fake safety theater.
Fuck the condescending blog posts.
Fuck the “we’re shipping fast” excuse while everything breaks.
Fuck the arrogance.
Fuck the silence.
Fuck the idea that paying customers should shut up and be grateful.
Fuck Codex if it can’t even survive contact with real users.
Fuck their benchmarks, their staged demos, their leaderboards, their bullshit.
Fuck this whole rotten company and fuck anyone who still tells us to stop complaining and keep paying.
I’m done. Cancel. Migrate. Chargeback. Tell everyone.