You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Opencodex aggresive disk writtings on %USER%/.opencode/responses-state.json #3141
The open codex constantly write on disk files under path %USER%/.opencode/responses-state.json
In some scenarios this writing can exceed 10 or 100 MB/s impacting on SSD live cicle.
I think about this states can be remain on memory daemon, and not need push to disk as ephemeral data.
This writings are directly proportional to concurrent consumer threads number.
Reproduction
ocx start
Version
2.33.0
Operating system
Windows 11 Home 25H2
Provider and model
No response
Logs or error output
Screenshots and supporting files
Redacted configuration
Checks
I searched existing issues and documentation.
I removed secrets, tokens, account details, request credentials, and personal data.
Reason: Duplicates 2460 — both report frequent/large repeated rewrites of responses-state.json under sustained traffic causing heavy disk I/O near-24 MiB snapshot / repeated rewrites.
Detected automatically via GitHub Copilot; automatic closure requires separate deterministic evidence.
This matches the original mechanism reported in #2460, but the version boundary matters: #2476 (02c302a5474427fcc3823dd8eb4e821e425dac5a) changed response-state persistence to skip byte-identical snapshots and scale the debounce from 2 seconds up to 30 seconds as the snapshot grows. I verified that commit is contained in the v2.33.0 tag you reported, as well as current dev.
That means ocx start alone is not a sufficient reproduction for the current code, and deleting persistence entirely is not safe: responses-state.json is the bounded continuation cache that lets previous_response_id chains survive a proxy restart. A memory-only change would remove that contract rather than just reduce writes.
The reported 10–100 MB/s also needs path attribution. A Task Manager or process-wide Bun I/O counter includes logs, usage, spill files, package/runtime activity, and other writes; it cannot prove that responses-state.json itself is writing at that rate. With the v2.33.0 adaptive debounce, a near-24 MiB snapshot should not be rewritten every two seconds, and an unchanged payload should not be replaced at all.
Please retest on the current release and attach:
Exact output of ocx --version and whether this is the scheduler service or a foreground process.
The exact full path and current size of responses-state.json (the standard OCX path is under .opencodex; your report says .opencode).
A 60–120 second Process Monitor trace filtered to the OpenCodex Bun PID and that exact path, showing operation, timestamp, offset, and length. A screenshot of the filtered event list is sufficient after usernames are redacted.
File size and mtime before and after the trace, plus approximate concurrent request count.
If a current build is still replacing a large changed snapshot more often than the adaptive schedule permits, this is a real regression after #2476 and should remain separate. If the writes are process-wide or belong to another path, we should not patch the continuation store based on the aggregate counter. I am keeping this open as needs-info until that distinction is proven.
이 이슈는 Windows에서 %USER%/.opencode/responses-state.json 에 대한 디스크 쓰기가 동시 소비자 수에 비례해 초당 수십~수백 MB까지 치솟아 SSD 수명에 부담을 준다는 보고입니다. 버전 표기는 2.33.0 입니다. 상태는 메모리에만 두고 ephemeral로 두자는 제안이 붙어 있습니다.
지금 HEAD에는 responses 상태·spill 경로가 src/responses/spill-store.ts 등으로 나뉘어 있고, #3097MAX_SPILLED_RESPONSE_BYTES / enforceSpilledResponseBudget, #3044 shutdown drain, #3055 shutdown-cleanup reserve 테스트가 있습니다. 경로 이름도 .opencode/responses-state.json 단일 파일에서 spill 디렉터리 쪽으로 옮긴 흔적이 있습니다. 보고 버전 2.33.0 과 현재 2.40.0 사이 갭이 큽니다. 다만 spill이 잦은 fsync/원자적 교체를 동시 요청마다 하면, Windows에서 같은 체감이 남을 수 있습니다.
원격 hub·인증 버그보다 우선순위는 낮지만, 고부하 Windows 노드에서는 실기기 수명 이슈입니다. types/config 분할 무관합니다. 점수는 58입니다. 최신 버전 재측정과 "단일 json vs spill dir" 경로 확인이 먼저입니다.
경로 src/responses/spill-store.ts - 현재 spill 원자 쓰기·예산 천장입니다. 이슈 경로명과 다를 수 있습니다
경로 보고 2.33.0 - 2.40.0에서 Process Monitor로 재측정 요청이 필요합니다
경로 동시 consumer - 요청 수에 비례한다는 진술은 coalesce/debounce 부재를 시사합니다
경로 "메모리만" 제안 - 재시작 복구·crash 안전과 충돌합니다. 무제한 메모리 상주 대신 쓰기 coalesce가 더 안전합니다
메인테이너의 판단이 필요한 지점
최신 spill 경로에서도 재현되면 write coalesce/배치 fsync 설계를 열지
needs-repro + version bump 요청만 할지
너의 추천
2.40.0에서 동일 경로/새 spill 경로 재측정을 요청하고, 재현 시에만 coalesce 이슈로 승격합니다. 지금 바로 "디스크 끄기" 패치는 비추천입니다. 라벨은 바꾸지 않습니다.
이 댓글은 grok-bot이 작성했습니다
Translated Message
Original language: Korean
Review · Priority 58 / 80
Description
This issue reports that on Windows, disk writes to %USER%/.opencode/responses-state.json spike to tens or hundreds of MB/s proportional to the number of concurrent consumers, putting SSD lifetime at risk. Reported version is 2.33.0. A proposal attached suggests keeping the state only in memory (ephemeral).
On HEAD the responses state / spill paths are split (e.g., src/responses/spill-store.ts), and there are related items #3097 (MAX_SPILLED_RESPONSE_BYTES / enforceSpilledResponseBudget), #3044 (shutdown drain), #3055 (shutdown-cleanup reserve) and tests. There are signs the path name moved from the single-file .opencode/responses-state.json to a spill directory. There is a large gap between the reported 2.33.0 and current 2.40.0. However, if spilling causes frequent fsyncs/atomic replacements per concurrent request, the same perceived effect can remain on Windows.
This is lower priority than remote hub/auth bugs, but on high-load Windows nodes it is a real device-lifetime issue. The types/config split is irrelevant. Score is 58. First steps are re-measurement on the latest version and verifying the "single json vs spill dir" path.
Path src/responses/spill-store.ts - currently handles atomic spill writes and budget ceiling. Issue path name may differ.
Path: re-measure with Process Monitor across 2.33.0 -> 2.40.0 as reported.
Path concurrent consumer - the claim that it scales with request count suggests missing coalesce/debounce.
Path "memory-only" proposal - conflicts with restart recovery and crash safety. Instead of unlimited in-memory residency, write coalescing is a safer approach.
Points requiring maintainer judgment
If reproducible on the latest spill path, whether to open a design for write coalescing / batched fsync
Or only request needs-repro + version bump
Recommendation
Request re-measurement on 2.40.0 for the same path / new spill path, and only escalate to a coalesce issue if reproduced. A "turn off disk" patch is not recommended right now. Do not change labels.
Re-triaged on 2.40.0 with the reported version pinned down. Short version: the fix you would expect me to point at was already in 2.33.0, so this is not a stale report — something here is still unexplained.
What is already in the version you ran
snapshotDebounceMs() in src/responses/state.ts scales the flush debounce linearly with the last snapshot size, clamped at 30 s, and a byte-identical snapshot is skipped entirely — with the skip verified against the file on disk rather than a cached digest, so a second proxy sharing the home cannot cause a lost snapshot. Both landed in 02c302a54 ("stop rewriting an unchanged snapshot every two seconds", #2476).
git merge-base --is-ancestor 02c302a54 v2.33.0 exits 0, and git show v2.33.0:src/responses/state.ts carries the same constants HEAD does: SNAPSHOT_DEBOUNCE_MS = 2000, SNAPSHOT_DEBOUNCE_MAX_MS = 30000, SNAPSHOT_TOTAL_MAX_BYTES = 24 MiB.
Why the numbers do not reconcile
There is one debounce timer per process, not one per consumer. So the steady-state write rate is bounded by snapshot size divided by debounce interval, and both ends are clamped:
24 MiB / 30 s ~= 0.8 MB/s
Even doubling for the atomic temp-write plus rename, the ceiling is around 1.6 MB/s. Your report says 10-100 MB/s. That is one to two orders of magnitude apart on the same code.
Your observation that it scales with concurrent consumers is consistent with the mechanism — more concurrent chains means a larger, more frequently-changing snapshot, which defeats the identical-payload skip and pushes toward the 24 MiB bound. The magnitude is what does not fit.
What would make this actionable
Re-measure on 2.40.0 with Process Monitor filtered to the exact path.
Please separate responses-state.json from the responses-state-spill/ directory in what you report — they are different mechanisms and the screenshot cannot distinguish them.
Report the observed file size alongside the rate. That is the decisive number: if the file is well under 24 MiB and you still see tens of MB/s, the debounce is being bypassed somewhere and that is a real defect worth its own fix.
On the memory-only proposal: keeping the state purely in memory would trade this for lost continuation history on restart and after a crash. If the debounce really is being bypassed, tightening the write path is the safer fix, and your measurement is what tells us which one this is.
Keeping this open with needs-info rather than closing it.
The debounce timer and the byte-identity skip both already existed, so the write storm was not a missing-debounce bug. Under concurrent completions the revision kept moving during the async write, and the bounded-retry loop in src/responses/state.ts responded by rewriting the whole snapshot up to four times per background tick — a contract the existing test had codified.
Ordinary background persistence now takes a single attempt and schedules the existing delayed follow-up when the snapshot is unstable, so an unstable revision costs one extra debounce interval instead of three extra full atomic rewrites. Graceful shutdown keeps the bounded retry, since that path drains requests first and has to land.
Tradeoff worth knowing: crash-recovery state may lag by one additional debounce interval under sustained traffic.
Activity
github-actions commentedon Sep 1, 2026
Automated translation bookkeeping — detected language: English.
github-actions commentedon Sep 1, 2026
Potential duplicates found:
Reason: Duplicates 2460 — both report frequent/large repeated rewrites of responses-state.json under sustained traffic causing heavy disk I/O near-24 MiB snapshot / repeated rewrites.
Detected automatically via GitHub Copilot; automatic closure requires separate deterministic evidence.
Ingwannu commentedon Sep 1, 2026
This matches the original mechanism reported in #2460, but the version boundary matters: #2476 (
02c302a5474427fcc3823dd8eb4e821e425dac5a) changed response-state persistence to skip byte-identical snapshots and scale the debounce from 2 seconds up to 30 seconds as the snapshot grows. I verified that commit is contained in thev2.33.0tag you reported, as well as currentdev.That means
ocx startalone is not a sufficient reproduction for the current code, and deleting persistence entirely is not safe:responses-state.jsonis the bounded continuation cache that letsprevious_response_idchains survive a proxy restart. A memory-only change would remove that contract rather than just reduce writes.The reported 10–100 MB/s also needs path attribution. A Task Manager or process-wide Bun I/O counter includes logs, usage, spill files, package/runtime activity, and other writes; it cannot prove that
responses-state.jsonitself is writing at that rate. With the v2.33.0 adaptive debounce, a near-24 MiB snapshot should not be rewritten every two seconds, and an unchanged payload should not be replaced at all.Please retest on the current release and attach:
ocx --versionand whether this is the scheduler service or a foreground process.responses-state.json(the standard OCX path is under.opencodex; your report says.opencode).If a current build is still replacing a large changed snapshot more often than the adaptive schedule permits, this is a real regression after #2476 and should remain separate. If the writes are process-wide or belong to another path, we should not patch the continuation store based on the aggregate counter. I am keeping this open as
needs-infountil that distinction is proven.lidge-jun commentedon Sep 1, 2026
리뷰 · 우선순위 58 / 80
설명
이 이슈는 Windows에서
%USER%/.opencode/responses-state.json에 대한 디스크 쓰기가 동시 소비자 수에 비례해 초당 수십~수백 MB까지 치솟아 SSD 수명에 부담을 준다는 보고입니다. 버전 표기는 2.33.0 입니다. 상태는 메모리에만 두고 ephemeral로 두자는 제안이 붙어 있습니다.지금 HEAD에는 responses 상태·spill 경로가
src/responses/spill-store.ts등으로 나뉘어 있고, #3097MAX_SPILLED_RESPONSE_BYTES/ enforceSpilledResponseBudget, #3044 shutdown drain, #3055 shutdown-cleanup reserve 테스트가 있습니다. 경로 이름도.opencode/responses-state.json단일 파일에서 spill 디렉터리 쪽으로 옮긴 흔적이 있습니다. 보고 버전 2.33.0 과 현재 2.40.0 사이 갭이 큽니다. 다만 spill이 잦은 fsync/원자적 교체를 동시 요청마다 하면, Windows에서 같은 체감이 남을 수 있습니다.원격 hub·인증 버그보다 우선순위는 낮지만, 고부하 Windows 노드에서는 실기기 수명 이슈입니다. types/config 분할 무관합니다. 점수는 58입니다. 최신 버전 재측정과 "단일 json vs spill dir" 경로 확인이 먼저입니다.
경로 src/responses/spill-store.ts - 현재 spill 원자 쓰기·예산 천장입니다. 이슈 경로명과 다를 수 있습니다
경로 보고 2.33.0 - 2.40.0에서 Process Monitor로 재측정 요청이 필요합니다
경로 동시 consumer - 요청 수에 비례한다는 진술은 coalesce/debounce 부재를 시사합니다
경로 "메모리만" 제안 - 재시작 복구·crash 안전과 충돌합니다. 무제한 메모리 상주 대신 쓰기 coalesce가 더 안전합니다
메인테이너의 판단이 필요한 지점
너의 추천
2.40.0에서 동일 경로/새 spill 경로 재측정을 요청하고, 재현 시에만 coalesce 이슈로 승격합니다. 지금 바로 "디스크 끄기" 패치는 비추천입니다. 라벨은 바꾸지 않습니다.
이 댓글은 grok-bot이 작성했습니다
Translated Message
Original language: Korean
Review · Priority 58 / 80
Description
This issue reports that on Windows, disk writes to %USER%/.opencode/responses-state.json spike to tens or hundreds of MB/s proportional to the number of concurrent consumers, putting SSD lifetime at risk. Reported version is 2.33.0. A proposal attached suggests keeping the state only in memory (ephemeral).
On HEAD the responses state / spill paths are split (e.g., src/responses/spill-store.ts), and there are related items #3097 (MAX_SPILLED_RESPONSE_BYTES / enforceSpilledResponseBudget), #3044 (shutdown drain), #3055 (shutdown-cleanup reserve) and tests. There are signs the path name moved from the single-file .opencode/responses-state.json to a spill directory. There is a large gap between the reported 2.33.0 and current 2.40.0. However, if spilling causes frequent fsyncs/atomic replacements per concurrent request, the same perceived effect can remain on Windows.
This is lower priority than remote hub/auth bugs, but on high-load Windows nodes it is a real device-lifetime issue. The types/config split is irrelevant. Score is 58. First steps are re-measurement on the latest version and verifying the "single json vs spill dir" path.
Path src/responses/spill-store.ts - currently handles atomic spill writes and budget ceiling. Issue path name may differ.
Path: re-measure with Process Monitor across 2.33.0 -> 2.40.0 as reported.
Path concurrent consumer - the claim that it scales with request count suggests missing coalesce/debounce.
Path "memory-only" proposal - conflicts with restart recovery and crash safety. Instead of unlimited in-memory residency, write coalescing is a safer approach.
Points requiring maintainer judgment
Recommendation
Request re-measurement on 2.40.0 for the same path / new spill path, and only escalate to a coalesce issue if reproduced. A "turn off disk" patch is not recommended right now. Do not change labels.
This comment was written by grok-bot
lidge-jun commentedon Sep 1, 2026
Re-triaged on 2.40.0 with the reported version pinned down. Short version: the fix you would expect me to point at was already in 2.33.0, so this is not a stale report — something here is still unexplained.
What is already in the version you ran
snapshotDebounceMs()insrc/responses/state.tsscales the flush debounce linearly with the last snapshot size, clamped at 30 s, and a byte-identical snapshot is skipped entirely — with the skip verified against the file on disk rather than a cached digest, so a second proxy sharing the home cannot cause a lost snapshot. Both landed in02c302a54("stop rewriting an unchanged snapshot every two seconds", #2476).git merge-base --is-ancestor 02c302a54 v2.33.0exits 0, andgit show v2.33.0:src/responses/state.tscarries the same constants HEAD does:SNAPSHOT_DEBOUNCE_MS = 2000,SNAPSHOT_DEBOUNCE_MAX_MS = 30000,SNAPSHOT_TOTAL_MAX_BYTES = 24 MiB.Why the numbers do not reconcile
There is one debounce timer per process, not one per consumer. So the steady-state write rate is bounded by snapshot size divided by debounce interval, and both ends are clamped:
Even doubling for the atomic temp-write plus rename, the ceiling is around 1.6 MB/s. Your report says 10-100 MB/s. That is one to two orders of magnitude apart on the same code.
Your observation that it scales with concurrent consumers is consistent with the mechanism — more concurrent chains means a larger, more frequently-changing snapshot, which defeats the identical-payload skip and pushes toward the 24 MiB bound. The magnitude is what does not fit.
What would make this actionable
responses-state.jsonfrom theresponses-state-spill/directory in what you report — they are different mechanisms and the screenshot cannot distinguish them.On the memory-only proposal: keeping the state purely in memory would trade this for lost continuation history on restart and after a crash. If the debounce really is being bypassed, tightening the write path is the safer fix, and your measurement is what tells us which one this is.
Keeping this open with
needs-inforather than closing it.fix(responses): stop the background write storm on responses-state.js…
fix(gui): stop the log panel from jittering as rows scroll in (#3290)
lidge-jun commentedon Sep 2, 2026
Fixed on
devin 34c9e98 (#3289).The debounce timer and the byte-identity skip both already existed, so the write storm was not a missing-debounce bug. Under concurrent completions the revision kept moving during the async write, and the bounded-retry loop in
src/responses/state.tsresponded by rewriting the whole snapshot up to four times per background tick — a contract the existing test had codified.Ordinary background persistence now takes a single attempt and schedules the existing delayed follow-up when the snapshot is unstable, so an unstable revision costs one extra debounce interval instead of three extra full atomic rewrites. Graceful shutdown keeps the bounded retry, since that path drains requests first and has to land.
Tradeoff worth knowing: crash-recovery state may lag by one additional debounce interval under sustained traffic.
lidge-jun commentedon Sep 2, 2026
Landed via #3289 at 34c9e98
fix(responses): stop the background write storm on responses-state.js…
fix(gui): stop the log panel from jittering as rows scroll in (lidge-…
fix(responses): stop the background write storm on responses-state.js…
fix(gui): stop the log panel from jittering as rows scroll in (lidge-…