Paginated thread bootstrap loads up to 500 items without a byte limit, so one large turn remains slow
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Rust
- Sterne
- 125k
- Forks
- 19.5k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Summary
A converted paginated task can still take tens of seconds to open because Codex Desktop uses a count-based initial item budget. It loads up to 500 recent items, without a byte-size limit.
One recent turn can therefore fill almost the complete initial window with large commandExecution items. Pagination prevents old history from loading, but it does not make the task interactive quickly.
The same remote task was slow in Codex Desktop on macOS and in Codex mobile. Mobile sometimes reported:
Error loading messages: Codex request timed out.
Environment
- Codex Desktop:
26.810.41047, build6570 - Platform: macOS, Apple Silicon
- Task host: remote Linux App Server over SSH
- Mobile used a separate reverse-tunnel route to the same remote App Server
- The task was confirmed as
historyMode: "paginated"
Private task IDs, host names, paths, prompts, and outputs are omitted.
Reproduction shape
The affected task had:
- rollout size: about 48.9 MiB
- 37 turns
- 974 persisted display items
- about 14.1 MiB of serialized display-item data
- latest completed turn: 420 items and about 10.8 MiB
commandExecution: 207 items and about 13.3 MiB across the task
Cold-load observations:
- stable
thread/resume: about 0.26 seconds - cold desktop hydration: about 28.8 seconds
- warm cached reopen: about 1.1 seconds
- ten sequential
thread/items/listrequests were observed during the cold load - some attempts reached the client timeout at about 65 seconds
- mobile also had long waits and a request-timeout error
This points to the initial item payload and client hydration, not rollout parsing or SQLite query time.
Desktop source finding
The installed Desktop bundle has a paginated tail-hydration path that:
- requests the newest five turns with
itemsView: "notLoaded"; - calls
thread/items/listrepeatedly; - uses a shared budget of
min(requested turn limit, 5) * 100, which is 500 items for the initial five-turn request; - asks for up to 100 items per item request;
- stops at 500 items or when the selected turns are exhausted;
- keeps cursors for older items.
The bundle also prevents the legacy full-history background drain for paginated tasks. The problem is therefore not that pagination is ignored. The problem is that the initial budget is based only on item count.
In this case, the newest 420-item turn alone contained about 10.8 MiB, so it remained almost fully inside the 500-item bootstrap window.
Expected behavior
A paginated task should become interactive after a small, byte-bounded bootstrap response, even when the newest turn contains many large command outputs.
The client should show the newest user and assistant messages quickly. Large command output and reasoning detail should load only when needed, or use compact placeholders.
Suggested direction
- Add a byte-size budget to initial item hydration.
- Use a much smaller initial item window when serialized items are large.
- Load full command output only when the user expands or scrolls to it.
- Keep user messages, assistant messages, file changes, turn status, and active output in the fast path.
- Do not block the composer or active-turn status on old command-output hydration.
- Apply the same bounded behavior to remote/follower and mobile paths.
Suggested regression test
Create a paginated fixture where the newest turn contains about 400 items and more than 10 MiB of command output.
Verify that:
- the first interactive render transfers a bounded payload;
- the composer becomes usable without loading all large output items;
- the complete output remains available on demand;
- desktop and remote/follower clients do not reach their request timeout;
- the original rollout and model-visible context remain unchanged.
Related issues
- #21211 — broad eager history hydration and renderer performance
- #34663 — CLI/TUI full-history resume behavior
- #33786 — repeated large-thread replay on Desktop
This report is narrower than those issues: it reproduces after the task is already converted to paginated history, and it identifies the 500-item, count-only bootstrap budget as the remaining large-payload path.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, den paginierten Tail-Hydration-Pfad zu finden, der die neuesten fünf Turns anfordert und das gemeinsame Budget von 500 Elementen anwendet, und untersuche anschließend dessen bestehende Behandlung von Elementlisten und Cursors. Verwende das vorgeschlagene Fixture mit etwa 400 Elementen und mehr als 10 MiB Command-Ausgabe. Als erledigt gilt, wenn der erste Render ein begrenztes Payload hat, der Composer verwendet werden kann, ohne die gesamte Ausgabe zu laden, die vollständige Ausgabe bei Bedarf weiterhin verfügbar ist und der ursprüngliche Rollout sowie der für das Modell sichtbare Kontext unverändert sind.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- rust
- Bereich
- desktop-dev, mobile-dev, performance
- Issue-Typ
- Bug
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Aktiv
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 35/100