Codex Desktop subagent session logs grow to 145GiB from repeated compacted replacement_history
Codex Desktop subagent session logs grow to 145GiB due to repeated compacted replacement_history
Summary
Codex Desktop appears to persist full compacted.replacement_history snapshots repeatedly inside subagent rollout JSONL files. In one long parent thread with many subagents, this produced about 145.76GiB of subagent session logs while user/main session history for the same period was only about 5.5MiB.
This looks like a session-retention / compaction logging bug rather than useful work output growth.
Product / area
- Product: Codex Desktop app
- Platform: macOS
- Observed local CLI version:
codex-cli 0.142.5 - Area: session storage, subagents, context compaction, retention policy
- Data sensitivity: raw session files may contain private user/project content; this report only includes aggregate/redacted evidence.
Duplicate check
Searched existing openai/codex issues for:
replacement_history subagent session logssession logs disk subagent
I found related session/performance issues, but not a direct duplicate for repeated compacted.replacement_history persistence in subagent rollout JSONL files.
Impact
~/.codex/sessionsgrew to roughly190G.- July sessions alone used about
146G. - The disk reached about
99%usage and left only about10GiBfree. - This blocks normal development/test workflows that need release builds, native UI verification, and longer runs.
- The large raw logs are still registered as active/unarchived session files, so manual deletion is risky.
Observed evidence
Read-only inventory of <HOME>/.codex/sessions/2026/07:
- Total indexed JSONL files:
641. thread_source=subagent:636files, about145.759GiB.thread_source=user:2files, about0.005GiB.thread_source=automation:6files, about0.002GiB.- Large subagent JSONL files
>=1GiB:71, total about145.450GiB. - Current-day/open files were not modified or touched.
Representative largest subagent JSONL:
- Raw file size: about
2.24GiB. - Lines:
156,005. - Top-level
compactedrecords:811. context_compactedmarkers:811.compacted/replacement_historypayload dominates storage.
Representative type breakdown:
type count bytes_mib pct
compacted 811 2127.71 92.96
event_msg.token_count 73663 51.91 2.27
event_msg.thread_goal_updated 18278 36.97 1.62
event_msg.patch_apply_end 9153 22.01 0.96
event_msg.agent_message 46144 21.68 0.95
response_item 2779 11.97 0.52
session_meta 284 7.38 0.32
turn_context 1672 2.46 0.11
Bounded scan of only the last 16MiB of each of the 71 large files:
task_completeseen in69/71files.- Evidence/tool/final-output refs are present, but tiny compared to repeated compaction payloads.
Expected behavior
Codex should not repeatedly persist full inherited replacement_history blobs per subagent/per compaction.
Expected alternatives:
- Store only the current compacted summary state.
- Store a digest/reference/backlink to an already persisted replacement history.
- Store a delta instead of the whole inherited history.
- Apply a retention policy that differentiates user/main chat history from subagent raw logs.
Actual behavior
Each large subagent rollout appears to persist full compacted.replacement_history snapshots repeatedly. In a long parent thread with many spawned subagents, this causes disk growth roughly proportional to:
number_of_subagents * number_of_compactions * replacement_history_size
This generated about 145.76GiB of subagent session logs from one parent-thread workflow.
Reproduction pattern
- Use a long Codex Desktop parent thread that has already gone through context compaction.
- Spawn many subagents from that parent thread.
- Let subagents continue far enough to compact context or persist inherited compacted context.
- Inspect
<HOME>/.codex/sessions/<year>/<month>/<day>/rollout-*.jsonl. - Compare
thread_source=subagentfile sizes and count top-levelcompactedrecords /replacement_historypayload size.
Read-only checks used
The investigation only used read-only commands such as:
du -sh ~/.codex/sessions/2026/07
find ~/.codex/sessions/2026/07 -type f -name '*.jsonl'
stat -f%z <file>
head -n 1 <file>
rg -a -c '"type":"compacted"' <file>
rg -a -c '"replacement_history"' <file>
sqlite3 -readonly ~/.codex/state_5.sqlite 'select thread_source, archived, count(*) from threads ...'
lsof +D ~/.codex/sessions/2026/07
Raw session files were not deleted, moved, edited, or attached.
Safety note
Please do not request raw .codex/sessions files unless there is a private upload channel. They contain private project/user content. A redacted ledger with aggregate counts can be provided.
Suggested fix direction
- Deduplicate
compacted.replacement_historyacross subagent rollouts. - Avoid storing full inherited replacement histories inside every child rollout.
- Add a bounded retention policy for subagent raw JSONL.
- Add a storage guard/alert when session logs exceed a threshold or when compacted payload dominates a rollout file.
- Make app-level archive/export handle subagent logs safely without breaking thread resume.
10 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Thanks for the duplicate pointers. I reviewed #30779 and #30932, and I agree this issue is related to both, but I do not think it is only a size-only duplicate.
The additional signal in this report is the combined failure mode:
compacted.replacement_historypayloads: the dominant multiplier appeared to be repeated full replacement-history snapshots inside compacted records.number_of_subagents * number_of_compactions * replacement_history_size.So my current read is:
If maintainers consider one of the other issues canonical, I am fine with closing this as a duplicate, but I think the
Desktop subagents × compactions × replacement_historymultiplier and the ~145GiB aggregate evidence should be kept attached to the canonical issue.Independent repro on Codex 0.144.6: one snapshot interval added 27.69 GB of rollout JSONL; 97.2% came from subagent rollouts. 15,983 inline-image occurrences consumed 23.63 GB, but represented only 69 unique values totaling 91.2 MB: 259× byte amplification. The two most frequent payloads were serialized 4,925 times each. Structural accounting only; no transcript text or image contents were inspected.
another data point on codex desktop 0.146.0-alpha.3.1 macos
one subagent rollout is 256 MB over 42765 lines
compacted is 254 records and 189 MB of that
session_meta is 519 records and 20.7 MB
the session_meta part looks separate from what is already in this thread
all 519 have the same session_id and each one repeats base_instructions at 21 KB and dynamic_tools at 20 KB
replacement_history itself stays bounded at around 212 entries and 430 KB so the compacted growth is the same snapshot written 254 times in a 33 minute session
in the last snapshot 210 of the 212 entries have role user
this was a read only review subagent that never sent a user message
if the rewritten history counts as user input then the next window fills straight away
no images in any of my files so this is not the inline image path
older ones look the same, 448 MB with 255 compacted records and 355 MB with 106
structural counts only, no transcript content inspected
Additional reproduction on macOS / Codex CLI 0.145.0
I found the same compaction-persistence pattern in a current macOS installation. This is a structural, redacted report; no raw rollout files are attached because they contain private prompts, paths, tool output, and project data.
Impact
~/.codexis approximately 362 GB.~/.codex/sessionsis approximately 354 GB across 6,596 JSONL files.Representative rollout
One representative JSONL file was:
compactedrecordscompactedrecords totalled 1,141,482,978 bytes (~93.3% of the file)event_msgandresponse_itemdata were comparatively smallThe 122
compactedrecords were appended within approximately 0.88 seconds (from 2026-07-22T01:19:32.543Z to about 2026-07-22T01:19:33.422Z), averaging about 9.36 MB per record. A second sampled rollout was approximately 1.09 GB with 108compactedrecords accounting for approximately 92.1%.This is not normal growth from useful conversation output. The rapid burst strongly suggests that a compaction result is being persisted and then reprocessed or persisted again before the compaction cycle terminates.
Trigger and local logs
The affected workflow was a long multi-agent/inter-agent session. Local logs show the compaction path entering
ContextLimitandcodex_core::compact_remote_v2::attempt, including messages indicating that history outputs were rewritten before remote compaction v2.The installed CLI reports:
The largest observed growth began before the local 0.145.0 package update, so this should be treated as an affected-version/current-regression data point rather than proof that the package update alone introduced the bug.
Expected behavior
After compaction, Codex should persist one bounded current state, a delta, or a reference to an existing compacted state. Previous compacted snapshots should not themselves become repeated input to another full snapshot. There should also be a per-rollout/per-session storage guard or retention policy.
Actual behavior
A long multi-agent session that reaches
ContextLimitcan append repeated fullcompactedsnapshots to the append-only JSONL history. In the observed case this produced hundreds of gigabytes of session data and at least one active rollout of approximately 2.66 GB.Reproduction pattern
ContextLimit.compactedrecords, sometimes emitted in a tight burst.compactedrecords.Please do not request raw session files publicly; they contain private data. I can provide further redacted aggregate statistics or a synthetic reproduction if needed.
Severe single-fork case: 153 MB child rollout in 64 seconds, followed by memory exhaustion and a forced reboot
I hit what appears to be the same subagent/compaction persistence bug on a 24 GB Apple Silicon Mac. In this case, the trigger was one successful
spawn_agentcall withfork_turns="all"from a large, image-heavy parent task.The parent rollout was already 2.77 GB. The new child grew to 153 MB in about 64 seconds and immediately began repeating the parent's image-bearing compaction pattern. Shortly afterward, ChatGPT/Codex climbed to roughly 34 GB, macOS became unresponsive, and I had to force a restart.
Environment
26.803.61601(build6396)151.0.7922.76codex-cli 0.147.0-alpha.6.5Darwin 25.5.0 arm64 arm26.5.1 (25F80)24 GiB019fe255-8774-7091-bbc5-ad106a42aed4019ffd06-f6c9-7653-8ac4-e2f72e77d764The child metadata identifies the parent and the subagent path
/root/repair_osint_journey.What happened
Times below are local, UTC-04:00, on August 13, 2026.
| Time | Event |
|---|---|
| 17:28:33.933 | Codex persisted the successful
spawn_agentrequest withfork_turns="all". || 17:28:39.909 | Child session metadata timestamp. |
| 17:29:10 | Child rollout created on disk. |
| 17:30:14 | Child rollout last modified. |
| 17:30:15 | Parent rollout last modified. |
| 17:30:43 | macOS created
.JetsamEvent-2026-08-13-173039.ips. The file is empty, apparently because collection did not finish before the restart. || 17:55:10 | Machine rebooted. I found no orderly shutdown entry or kernel panic report. |
The child never reached the implementation work it had been assigned.
Rollout measurements
Parent
| Metric | Value |
|---|---:|
| File size |
2,770,032,159bytes || JSONL records |
24,530|| Top-level
compactedrecords |50|| Bytes in those records |
2,539,635,323(91.68%of the file) || Largest single
compactedrecord |93,957,345bytes || Compacted records containing
data:image|50 / 50|| SQLite
tokens_used|872,191,112|Child
| Metric | Value |
|---|---:|
| File size after about 64 seconds |
153,405,788bytes || JSONL records |
1,198|| Top-level
compactedrecords |10|| Bytes in those records |
106,648,439(69.52%of the file) || Largest single
compactedrecord |31,264,650bytes || Compacted records containing
data:image|10 / 10|| SQLite
tokens_used|77,804,368|The token counts are included as evidence of repeated context processing. They should not be read as unique generated-text tokens.
The clearest signal here is the child's behavior: one full-history fork created a 153 MB rollout in roughly a minute, before doing useful work, and all 10 of its compaction records contained inline image data.
Other system evidence
The incomplete August 13 Jetsam artifact cannot tell us which process held the memory during the fatal event. A completed Jetsam report from August 12 on the same installation shows that this was not the first serious memory-pressure event:
24.091 GiBon a 24 GiB machine.codexprocess had peaked at22.147 GiB.180 node,29 node_repl,24 python3.10, and23 uvprocesses.Two macOS diagnostics from August 11 also attributed heavy disk writes to
codex:34.36 GBover3,198seconds, with a maximum footprint of18.81 GB.137.44 GBover8,735seconds.Those earlier reports are supporting evidence only; they are not measurements from the exact August 13 failure window. The unusually large process tree may also point to the cleanup problem reported in #12491, but I cannot show that it caused this particular crash.
Why this looks like a fork/compaction amplification bug
I compared the rollout evidence with
openai/codexatorigin/maincommit85f331772f54a9d518fefa6b1596cbde8cd78fd1. The installed app may not be byte-for-byte identical to that commit, but the current source describes the same sequence visible in these files:fork_turnsdefaults toall, which maps toFullHistory.InitialHistory::Forked.Copied, and the non-paginated path writes the inherited prefix into the child's rollout.In other words, an image-bearing replacement history can be copied from parent to child and then cloned again each time the child compacts. This case connects the behavior reported in #36557, #33493, and #34863.
Expected behavior
Reference-backed fork persistence looks like the natural fix for the first part. Large images should also be stored once and referenced by ID or content hash, with explicit limits on the number and encoded size retained during compaction.
A useful regression test would create an image-bearing compacted parent, spawn one
fork_turns="all"child, compact that child several times, and assert that both rollout size and process memory remain bounded.Privacy note
I cannot attach the raw rollout files publicly. They contain private project history, screenshots, prompts, local paths, and tool output. I can provide the following through a private OpenAI upload channel:
The 145.76 GiB of subagent rollouts is a strong bounded-diagnostics case, especially the 2.24 GiB child with 811 persisted
replacement_historysnapshots and terminal events near the tail.I’m testing whether Codex Rescue can enumerate and inspect this real session tree without loading or copying full histories. It will not prune subagents, compress records, or modify active/unarchived rollouts. The source remains untouched and any uncertain continuation state stays fail-closed.
If the retained files are still available, could you run:
pipx install codex-rescue==0.1.0a3codex-rescue sessionscodex-rescue doctor --latestSanitized counts/status only are sufficient—please don’t share JSONL, databases, tool output, prompts, project content, private paths, or secrets.
https://github.com/shleder/codex-rescue
Confirmed this is still reproducible in the current ChatGPT desktop build:
26.810.52044(build6662)codex-cli 0.148.0-alpha.926.6.1(25G76)On 2026-08-17,
~/.codexhad grown to about 309 GiB, leaving the disk 99% full with about 12 GiB free. The normal app log directory was only about 64 MiB. Almost all usage came from rollout JSONL files:A representative 5.48 GiB rollout had
thread_source: subagent, multi-agent v1, and was forked from an older parent task. It contained:replacement_historyrecordscompactedrecordsinput_imageThis appears to be the same repeated
compacted.replacement_historygrowth reported here. The image duplication aspect also overlaps #39013, which reports the same desktop app/build, and the full-history fork behavior described in #34268.I have not attached the raw rollout files because they contain private conversation and image data. I can provide additional sanitized counts if useful.
Confirming repeated
compacted.replacement_historygrowth on a current Desktop build:26.818.61809build7019codex-cli 0.149.0-alpha.4.326.6.1 (25G76), arm64A reproducible, modification-time-fenced scan of 368 local rollouts produced:
The scan retained only structural classes and byte counts; it excluded transcript content, paths, filenames, thread IDs, and timestamps.
Each of the eight ≥1 GiB rollouts was 91.4–94.8% compacted records by byte size. The largest was a 13.26 GB root/VS Code rollout, with 12.12 GB in 399 compacted records. The next seven were subagent rollouts. This shows that the same storage multiplier affects both inherited child histories and root threads.
A 202 MB rollout in the same store was only 1.4% compacted by byte size, providing a negative control for the classifier.
Current public source at
c3953649156e15b67e572cb9e38bc825a811c24estill:replacement_history: Some(items.clone());Vecon the full-history path.Cold compression and retained-image budgeting are useful partial mitigations, but they do not bound active rollout growth or repeated non-image replacement histories.
The storage invariant should be:
One implementation direction is to persist immutable checkpoint payloads once and let compacted records reference them. The corresponding regression should repeatedly compact a stable large history and assert sublinear physical growth.
The remaining design boundary is preserving resume, rollback, fork, window-lineage, world-state, and late-suffix behavior while making checkpoint storage proportional to unique retained history.
Confirming the replacement_history growth shape here as well. For measurement:
vetto rescue --json scanreports per-session bytes read-only, which makes the compaction-amplification claim concrete (before/after numbers per thread) without touching provider state.