Summary
Imaged requests become unreliable once the rendered wire payload passes roughly 20 MiB.
Below that line, success is essentially 100%.
Above it, requests fail as 500, 502, empty 200 (status 200 with no usage/tokens and no usable content), or stall for up to 5 minutes.
pxpipe applies no upper bound on rendered image bytes, so a long session drifts into this zone on its own.
The part that turns this from "occasional retry" into "stuck session" is that /compact cannot escape it, because compaction sends the same oversized history through the same compression path.
Evidence
From my own ~/.pxpipe/events.jsonl, 10,257 imaged requests over 2026-07-10 to 2026-07-28, models claude-opus-5 and claude-fable-5.
"ok" means status 200 with a non-zero input token count.
| rendered payload |
n |
ok |
fail |
success rate |
| 0-8 MiB |
7965 |
7943 |
22 |
99.7% |
| 8-14 MiB |
1074 |
1056 |
18 |
98.3% |
| 14-18 MiB |
683 |
658 |
25 |
96.3% |
| 18-19.5 MiB |
257 |
257 |
0 |
100.0% |
| 19.5-20 MiB |
84 |
84 |
0 |
100.0% |
| 20-21 MiB |
119 |
96 |
23 |
80.7% |
| 21-24 MiB |
77 |
50 |
27 |
64.9% |
341 consecutive requests between 18 and 20 MiB succeeded without a single failure, so the degradation onset is sharp and sits right around 20 MiB.
Failure modes above 19.5 MiB:
| model |
outcome |
n |
payload range |
claude-opus-5 |
500 |
8 |
20.08 MiB |
claude-opus-5 |
empty 200 |
8 |
20.08 MiB |
claude-fable-5 |
502 |
19 |
20.25-21.20 MiB |
claude-fable-5 |
empty 200 |
11 |
20.26-21.85 MiB |
claude-fable-5 |
500 |
3 |
21.85 MiB |
claude-fable-5 |
stall, 120s-317s |
11 |
20+ MiB |
This is a reliability cliff, not a hard cap.
claude-fable-5 has 202 successes in the 19.74-21.64 MiB range, including a clean 200 at 21.64 MiB with 315 images.
So requests above 20 MiB are sometimes served and sometimes not.
The mix of 502, empty 200, and multi-minute stalls points at an upstream edge or gateway behavior on large request bodies rather than a model-level limit.
I want to be explicit about the limit of my evidence here: I have not captured an upstream error body.
pxpipe discards 5xx bodies unless PXPIPE_DEBUG_CAPTURE_4XX=1, so the classification above is inferred from status, timing, and size, not from the server's own error text.
Why this is invisible until it breaks
The Claude Code context meter is a token measure, and compression is doing its job on tokens.
The failure is a byte measure on the wire.
Those move in opposite directions, so there is no warning signal.
In the session where I hit this, the meter showed 32% of a 1M context window while the rendered payload on the wire was 20.08 MiB and every request was failing.
Nothing surfaced in the dashboard indicated that wire bytes were the problem.
The actual blocker: compaction deadlock
Once a session is above the line, the normal remedy is /compact.
That fails too, with the same signature:
Error during compaction: API Error: 500 Internal server error.
Compaction has to send the history it is trying to summarize, that history is what exceeds 20 MiB, and it goes through compression like any other request.
So the session has no in-band way out.
That is the part I would prioritize.
Workaround that recovered the session
- Disable compression for the model (dashboard chip / global toggle), keeping the same model.
- Run
/compact, which now goes as plain text and succeeds.
- Re-enable compression and continue.
The session survived with no model switch and no context loss.
It does require knowing that wire bytes are the cause, which is not discoverable from any surfaced signal.
Suggested fixes
- Image-byte budget. Cap projected rendered bytes per request, configurable, defaulting somewhere safely under the onset (18 MiB would sit inside a 341-request zone with zero observed failures). When the next block would cross the cap, pass it through as text instead of rendering it. Degraded savings beats a failed request.
- Always leave compaction an escape hatch. Compaction and summarization requests should bypass compression, or use a much lower budget, so a session can always shrink itself back under the line.
- Graceful degradation on large-payload failures. For payloads above the threshold, retry once with compression disabled on
500, 502, or empty 200, rather than surfacing a hard API error.
- Surface wire bytes. Show rendered payload bytes and image count per request in the dashboard, with a warning as the cap approaches. Token savings alone actively hides this failure.
Environment
pxpipe-proxy 0.11.1
- Claude Code 2.1.220 (CLI), 2.1.219 (desktop bundle)
- Node v22.18.0
- macOS (Darwin 25.5.0), Apple Silicon
- Models:
claude-opus-5 (1M context, launched as --model opus[1m]) and claude-fable-5
- Upstream:
api.anthropic.com via a local proxy chain
Summary
Imaged requests become unreliable once the rendered wire payload passes roughly 20 MiB.
Below that line, success is essentially 100%.
Above it, requests fail as
500,502, empty200(status 200 with no usage/tokens and no usable content), or stall for up to 5 minutes.pxpipe applies no upper bound on rendered image bytes, so a long session drifts into this zone on its own.
The part that turns this from "occasional retry" into "stuck session" is that
/compactcannot escape it, because compaction sends the same oversized history through the same compression path.Evidence
From my own
~/.pxpipe/events.jsonl, 10,257 imaged requests over 2026-07-10 to 2026-07-28, modelsclaude-opus-5andclaude-fable-5."ok" means status 200 with a non-zero input token count.
341 consecutive requests between 18 and 20 MiB succeeded without a single failure, so the degradation onset is sharp and sits right around 20 MiB.
Failure modes above 19.5 MiB:
claude-opus-5500claude-opus-5200claude-fable-5502claude-fable-5200claude-fable-5500claude-fable-5This is a reliability cliff, not a hard cap.
claude-fable-5has 202 successes in the 19.74-21.64 MiB range, including a clean 200 at 21.64 MiB with 315 images.So requests above 20 MiB are sometimes served and sometimes not.
The mix of
502, empty200, and multi-minute stalls points at an upstream edge or gateway behavior on large request bodies rather than a model-level limit.I want to be explicit about the limit of my evidence here: I have not captured an upstream error body.
pxpipe discards 5xx bodies unless
PXPIPE_DEBUG_CAPTURE_4XX=1, so the classification above is inferred from status, timing, and size, not from the server's own error text.Why this is invisible until it breaks
The Claude Code context meter is a token measure, and compression is doing its job on tokens.
The failure is a byte measure on the wire.
Those move in opposite directions, so there is no warning signal.
In the session where I hit this, the meter showed 32% of a 1M context window while the rendered payload on the wire was 20.08 MiB and every request was failing.
Nothing surfaced in the dashboard indicated that wire bytes were the problem.
The actual blocker: compaction deadlock
Once a session is above the line, the normal remedy is
/compact.That fails too, with the same signature:
Compaction has to send the history it is trying to summarize, that history is what exceeds 20 MiB, and it goes through compression like any other request.
So the session has no in-band way out.
That is the part I would prioritize.
Workaround that recovered the session
/compact, which now goes as plain text and succeeds.The session survived with no model switch and no context loss.
It does require knowing that wire bytes are the cause, which is not discoverable from any surfaced signal.
Suggested fixes
500,502, or empty200, rather than surfacing a hard API error.Environment
pxpipe-proxy0.11.1claude-opus-5(1M context, launched as--model opus[1m]) andclaude-fable-5api.anthropic.comvia a local proxy chain