Repository navigation
Description
Managed background service startup can take minutes and saturates the disk; the CLI's short health check turns it into a spawn/retry storm
Summary
On a machine whose only data disk is a spinning HDD, launching opencode makes the whole box
unresponsive (a remote session to the machine drops, other local services stall) while the
terminal sits on Starting background server....
The service process is not memory-bound and not CPU-bound. It is bound on file I/O
against its own SQLite store: ~1.4 GB of file I/O (reads and writes roughly 1:1) with only
~10 s of CPU time and a stable ~300 MB RSS. On this machine that saturates the disk for minutes.
Meanwhile the CLI's health check gives up after roughly 10 seconds, reports
Background service is unresponsive, and starts another service — so the same multi-minute
disk-hammering startup is repeated, and the extra processes collide on the managed service port.
Environment
- opencode
2.0.27(installed as the npm package@opencode/cli; the bundled Bun runtime in
opencode.exereports Bun1.4.2) - Windows Server 2025 Standard, build
26100, x64 - 16 GB RAM, page file 6.4 GB
- Single data disk: 4 TB SATA HDD (Seagate SkyHawk
ST4000VX016). No SSD on the machine. - Data directory
C:\Users\<user>\.local\share\opencode:opencode.db— 5,239,611,392 bytes;page_size=4096,page_count=1,279,202,
freelist_count=917,638⇒ ~3.76 GB (72 %) of the file is free pages, live data ≈ 1.4 GBopencode.db-wal— 314,096,472 bytes (≈76,237 frames of 4096 B),journal_mode=wal- Content: 984 sessions, 38,409 messages, 245,697 parts
- A third-party npm plugin is configured in
opencode.jsonc - Windows Defender real-time protection is off on this machine, so AV scanning is ruled out
Log evidence
CLI start that never converges (retry storm, and a managed-service port that is already taken by
the still-initializing child):
timestamp=2026-10-12T09:10:53.445Z level=INFO run=419b0ea5 message="cli starting" version=2.0.27 args=[] role=cli
timestamp=2026-10-12T09:10:53.505Z level=INFO run=419b0ea5 message="background service starting" reason=missing previousVersion=undefined role=cli
timestamp=2026-10-12T09:11:04.385Z level=WARN run=419b0ea5 message="Background service is unresponsive; recovery cannot preserve persistent terminals" role=cli
timestamp=2026-10-12T09:11:15.621Z level=WARN run=419b0ea5 message="Background service is unresponsive; recovery cannot preserve persistent terminals" role=cli
timestamp=2026-10-12T09:11:20.242Z level=INFO run=2fb50173 message="cli starting" version=2.0.27 args="[\"serve\",\"--service\"]" role=cli
timestamp=2026-10-12T09:11:29.285Z level=INFO run=83781822 message="cli starting" version=2.0.27 args="[\"serve\",\"--service\"]" role=cli
timestamp=2026-10-12T09:11:40.223Z level=ERROR run=2fb50173 message="cli process failed" cause="...Error: Managed service port 49374 on 127.0.0.1 is already in use by another process..."
timestamp=2026-10-12T09:11:48.942Z level=ERROR run=83781822 message="cli process failed" cause="...Error: Managed service port 49374 on 127.0.0.1 is already in use by another process..."
The same pattern repeats earlier in the log, including
cli process failed ... Error: Timed out waiting for the background service to start.
Startup that is allowed to finish (standalone opencode serve, no CLI in the way) — note the
six-minute silent gap between process start and the first database work, and that the first
log line after that gap is the migration, i.e. nothing is logged while the slow phase runs:
timestamp=2026-10-12T11:28:37.552Z level=INFO run=2785f61a message="cli starting" version=2.0.27 args="[\"serve\",\"--hostname\",\"127.0.0.1\",\"--port\",\"49831\"]" role=cli
timestamp=2026-10-12T11:34:34.803Z level=INFO run=2785f61a message="database migration started" migration=20261010180456_project_time_archived role=server
timestamp=2026-10-12T11:34:34.867Z level=INFO run=2785f61a message="database migration completed" migration=20261010180456_project_time_archived durationMs=64 role=server
$ opencode serve --hostname 127.0.0.1 --port 49831
server listening on http://127.0.0.1:49831 # reached ~6 minutes after process start
Measurements
opencode --version finishes in 0.3 s with a ~2.6 MB working set, so the Bun runtime and
binary loading are not the problem.
opencode serve --hostname 127.0.0.1 --port <p>, sampled every 2 s for 152 s
(process started at idle CPU priority, affinity restricted to one core, killed afterwards):
| metric | value |
|---|---|
| elapsed | 152 s |
| process file I/O | 1.41 GB (reads and writes roughly 1:1) |
| CPU time | 10.6 s |
| working set | 270–320 MB, stable |
\PhysicalDisk(_Total)\% Idle Time |
0–2 % (disk saturated) |
| disk queue length | peaks at 5–7 |
| disk avg transfer latency | peaks at 352 ms, also 73 ms / 57 ms spikes |
| files written during the whole run | only opencode.db and opencode.db-wal |
The only file I/O targets observed were the SQLite database and its WAL; the plugin cache,
config dir, state dir and temp dirs were untouched (verified by scanning for files modified
during the run).
Two runs of the same command:
| run | time from cli starting to server listening |
|---|---|
| cold file cache | 5 min 59 s |
| 11 minutes later (warm cache) | ~100 s |
Reproduction
- Windows with a spinning HDD as the data disk (this is the environment that freezes; the same
startup on an SSD is presumably just slow). - Use a store that looks like a long-lived one: a multi-GB
opencode.dbwith a high
freelist_countratio, plus a largeopencode.db-wal(~300 MB here). opencode --version→ completes in ~0.3 s.opencode serve --hostname 127.0.0.1 --port <free port>→ observe that
server listening on ...is printed minutes later; sample the process I/O counters
(Win32_Process.ReadTransferCount/WriteTransferCount) and
\PhysicalDisk(_Total)\% Idle Timewhile it runs.- Run
opencode(default TUI) in any directory with the machine otherwise idle and watch
~/.local/share/opencode/log/opencode.log:background service starting, then
Background service is unresponsiveabout 10 s later, then repeatedserve --service
children failing withManaged service port ... is already in use by another process.
Analysis / hypothesis
- The service does a large amount of SQLite work before it can serve
/api/info. Reads and
writes are close to 1:1 (~266 MB read / ~261 MB written in one 71 s window), which is the
shape of a WAL checkpoint / page copy into the main database rather than a pure scan.
On a 5.2 GB file that is 72 % free pages, with a 300 MB WAL, the scattered page writes are
expensive; on an HDD they saturate the device (0 % idle, 350 ms transfer latency spikes) and
stall every other process on the machine. - The CLI's health check (~10 s) and the real startup time (100 s warm, ~6 min cold) are off by
one to two orders of magnitude, so the CLI declares the service dead while it is still
initializing. - Because the CLI then starts another service, and the previous child still holds the managed
port, the retry storm amplifies the disk load and produces the misleading
port ... is already in useerrors. - If the user kills the frozen CLI (the natural reaction), the checkpoint never completes, so
the large WAL survives and the next launch repeats the same work. The store's free-page
ratio then keeps growing, which makes the next startup slower — a feedback loop.
Suggested directions
- Do not start a new managed service while a previous child is still within its startup window;
make the health check adapt to the child's progress instead of a fixed ~10 s deadline, and
report the child's exit/state rather thanport already in use. - Log the phases that currently run silently: there is a multi-minute window with no log output
at all betweencli startinganddatabase migration started. - Avoid heavy store work before the server can answer basic health endpoints (answer
/api/infoearly / return 503 fast while initialization continues), so a health check can
succeed early. - Bound the WAL: a killed process should not leave ~300 MB of WAL that must be re-checkpointed on
every launch (PRAGMA journal_size_limit, plus a checkpoint on clean shutdown). - Handle extreme free-page ratios: 72 % of a 5.2 GB file was freed pages here, which multiplies
the I/O of any checkpoint. A periodic/one-offVACUUM(or incremental autovacuum) when the
freelist ratio crosses a threshold would keep startup bounded as history grows. - Surface this to users: the docs/TUI could warn that the first start after a long history (or on
an HDD) can take minutes and must not be interrupted.
Workaround
With opencode fully closed, shrink the store offline so the next start has far less to do:
PRAGMA wal_checkpoint(TRUNCATE);
VACUUM;and do not interrupt the first start after that — it is a one-time cost, whereas killing it
keeps the state that makes every following start slow again. (Not yet executed on this machine;
the offline repair is the planned next step.)
中文版(同一 issue 的中文说明)
概要
在一台只有一块机械硬盘作为数据盘的机器上启动 opencode,终端停在
Starting background server...,整机随之失去响应(对这台机器的远程会话断开、其他本地服务
一起卡住)。
服务进程既不是内存瓶颈、也不是 CPU 瓶颈,而是卡在对自己 SQLite 存储的文件 I/O 上:
约 1.4 GB 文件 I/O(读写大致 1:1),CPU 仅约 10 秒,RSS 稳定在约 300 MB。在这台机器上,
这会把它唯一的磁盘打满数分钟。
与此同时,CLI 的健康检查大约 10 秒就放弃,报 Background service is unresponsive,然后又去
启动一个服务——于是这套耗时数分钟的、把磁盘打满的启动被反复执行,新老进程还会争抢托管
服务端口。
环境
- opencode
2.0.27(npm 包@opencode/cli安装;opencode.exe内置的 Bun 运行时报告
Bun1.4.2) - Windows Server 2025 Standard,build
26100,x64 - 16 GB 内存,页面文件 6.4 GB
- 数据盘只有一块 4 TB SATA 机械硬盘(Seagate SkyHawk
ST4000VX016),机器上没有 SSD - 数据目录
C:\Users\<user>\.local\share\opencode:opencode.db— 5,239,611,392 字节;page_size=4096、page_count=1,279,202、
freelist_count=917,638⇒ 约 3.76 GB(72%)是空洞页,真实数据约 1.4 GBopencode.db-wal— 314,096,472 字节(约 76,237 帧 × 4096 B),journal_mode=wal- 内容规模:984 个会话、38,409 条 message、245,697 条 part
opencode.jsonc中配置了一个第三方 npm 插件- 该机器的 Windows Defender 实时防护是关闭的,因此可以排除杀软扫描
日志证据
见上文英文部分的两个日志片段:一个是 CLI 始终无法收敛的启动(先是 10 秒后判定"服务无响应",
随后多个 serve --service 子进程因托管端口已被占用而失败);另一个是允许它跑完的
opencode serve 启动,可以看到进程启动与第一次数据库操作之间有近 6 分钟的静默空档,
即这段最慢的阶段完全没有日志输出。
测量
同样见上文英文部分的表格:opencode --version 0.3 秒完成、工作集约 2.6 MB(说明运行时不
是问题);opencode serve 实测 152 秒内产生 1.41 GB 文件 I/O、CPU 仅 10.6 秒、内存
稳定 270–320 MB,而磁盘 % Idle Time 只有 0–2%(被打满)、队列峰值 5–7、单次传输延迟
峰值 352 ms;整个过程中被写入的文件只有 opencode.db 和 opencode.db-wal
(插件缓存、config、state、临时目录都没有文件被写)。
同一命令两次运行的差别:冷缓存时从 cli starting 到 server listening 用了
5 分 59 秒;11 分钟后再跑(缓存已热)约 100 秒。
复现
- Windows 机器,数据盘为机械硬盘(这是会卡死的环境;SSD 上大概只是慢)。
- 准备一个"长期使用过"的存储:数 GB 的
opencode.db且freelist_count占比很高,外加一个
较大的opencode.db-wal(本例约 300 MB)。 opencode --version→ 约 0.3 秒返回。opencode serve --hostname 127.0.0.1 --port <空闲端口>→ 观察server listening on ...
要等数分钟才打印;期间采样进程 I/O 计数
(Win32_Process.ReadTransferCount/WriteTransferCount)与
\PhysicalDisk(_Total)\% Idle Time。- 在任意目录运行
opencode(默认 TUI),机器保持空闲,观察
~/.local/share/opencode/log/opencode.log:先是background service starting,约 10 秒后
Background service is unresponsive,接着多个serve --service子进程以
Managed service port ... is already in use by another process失败。
分析与假设
- 该服务在能够响应
/api/info之前做了大量 SQLite 工作。读写量接近 1:1(一个 71 秒窗口内
读约 266 MB、写约 261 MB),这个形态更像是把 WAL 页回拷进主库的 checkpoint,而不是
纯扫描。在一个 5.2 GB、其中 72% 是空洞页、外加 300 MB WAL 的文件上,这些分散的页写入
代价很高;在机械盘上就直接打满设备(%idle 0、延迟峰值 350 ms),把机器上其他进程一起拖住。 - CLI 的健康检查(约 10 秒)与真实启动耗时(热 100 秒、冷约 6 分钟)差一到两个数量级,
因此它在服务仍在初始化时就判定其已死。 - 之后 CLI 再启动一个服务,而前一个子进程仍占着托管端口,于是重试风暴放大了磁盘负载,并
产生误导性的port ... is already in use报错。 - 如果用户在卡死时把 CLI 杀掉(这是很自然的反应),checkpoint 永远无法完成,大体积 WAL
被保留,下次启动又要重做同样的工作;同时空洞页比例继续增长,使下一次启动更慢——形成
正反馈。
建议方向
- 前一个子进程仍在启动窗口内时,不要启动新的托管服务;健康检查应随子进程的进展自适应,
而不是固定的约 10 秒死线;并且应上报子进程的真实状态,而不是port already in use。 - 给目前完全静默的阶段加日志:从
cli starting到database migration started之间存在
数分钟没有任何输出的空档。 - 在服务能响应基础健康端点之前,避免做重量级存储工作(例如先快速响应
/api/info或按
503 快速失败,把重活放到后台继续),这样健康检查可以更早通过。 - 限制 WAL 体积:进程被杀之后不应留下约 300 MB 的 WAL 让每次启动重新 checkpoint
(PRAGMA journal_size_limit,以及干净退出时做一次 checkpoint)。 - 处理极端的空洞页比例:本例 5.2 GB 的文件里有 72% 是已释放页,会让任何 checkpoint 的 I/O
成倍放大。当 freelist 比例超过阈值时做一次VACUUM(或启用增量 autovacuum),可以让
启动开销随历史增长仍然可控。 - 让用户可见:文档/TUI 可以提示"历史很长时(或在机械盘上)首次启动可能长达数分钟,请勿中断"。
规避办法
在 opencode 完全关闭的情况下,离线收缩存储,让下一次启动少做很多事:
PRAGMA wal_checkpoint(TRUNCATE);
VACUUM;之后不要中断第一次启动——那是一次性代价;而杀掉它恰好会保留让每次启动都变慢的状态。
(本机尚未执行,离线修复是下一步计划。)
Activity
opencode-agent commentedon Oct 12, 2026
Thanks for the detailed report and measurements. I could reproduce this on 2.0.27, and it still happens on the latest
dev(bcf23b6).What I did on Linux, with a fresh data directory:
sqlite3writer killed before it could checkpoint).strace.opencode service start.The log shows
Background service is unresponsiveabout every 11 seconds. Each time the CLI kills the service that is still starting and spawns a new one. The WAL checkpoint never finishes, so the main database file never grows. Ondevone of the extra services also failed withManaged service port ... is already in use by another process, the same error you saw. Without the slowdown, the same store starts in under a second.The script below reproduces it. I couldn't test the machine-wide freeze, since that needs a real HDD, but the kill-and-respawn loop that repeats the expensive startup work is confirmed.
Related: #41739 (similar stall on a large database, caused there by the V1 migration), #54267 (port already in use while an older service is still alive), #54181 and #37795 (a busy service treated as dead by short health probes).
Reproduction script (repro.sh)
Run it:
bash repro.shOhnkytaBlabdey commentedon Oct 12, 2026
Follow-up: offline repair results, a correction, and what actually writes to the store at startup
1. Correction to the original report
The original report suggested that a ~300 MB WAL had to be re-checkpointed on every launch. I
have to withdraw that as a mechanism: on this machine the WAL file was 314,096,472 bytes but
PRAGMA wal_checkpoint(TRUNCATE)returned0|0|0, i.e. the file had simply never beentruncated and there was nothing to say it held pending frames. The measured facts in the
original report (duration, I/O volume, CPU, RSS, disk saturation) stand; the "300 MB
re-checkpoint each launch" explanation does not, and the real writer is described in §3 below.
2. Offline repair (store shrunk, startup no longer minutes)
Performed with opencode fully closed, on the same machine:
Results:
opencode.dbfreelist_count)opencode.db-walintegrity_checkokTotal wall time for the three steps: 5 min 09 s (77 s for
VACUUM INTO, 228 s forVACUUM).Effect on startup, same command line (
opencode serve --hostname 127.0.0.1 --port <p>), samemachine:
server listeningSo the multi-minute startup is gone. This is on a machine whose only disk is a 4 TB SATA HDD.
3. What still writes: startup populates the v2 tables
The repair does not stop the heavy writes. In short guarded runs after the repair, the
process still performed 0.7–1.4 GB of file I/O in the first ~1 minute, and the store kept
growing even though the v1 row counts never changed.
Measured before → after the first start → after a second start:
sessionmessagepartsession_v2session_messageopencode.dbsizefreelist_countObservations:
session_v2/session_message(the v2-shaped tables), populatedfrom the existing v1 data (
session/message/part), whilepartcontent is untouched.session_v20 → 668 → 863 out of984 sessions) and costs ~170–320 MB of store growth and ~0.7–1.4 GB of I/O.
unresponsive, it has been interrupted every time, so the backfill never finishes and every
launch repeats a large chunk of work. The store had reached 5.24 GB with 72 % free pages
this way.
0.7–1.4 GBfor what is effectively "continue migrating my ownhistory") is also what keeps the machine unusable during the first minute of a start, even
after the store has been compacted.
Questions:
resumable/idempotent? Can it be run to completion offline (a CLI command, or a documented
"migrate and exit"), instead of depending on the server surviving long enough?
cli startingand the migrationlines — could the backfill report progress so users don't have to guess whether it is hung?
not need to rewrite the whole store while the user is waiting for a TUI?
4. Reproduction
The same growth is visible as
PRAGMA page_countincreasing by tens of thousands of pages perstart while
PRAGMA freelist_countstays 0.5. Update: the backfill does finish, and after that the start is quiet
A third start was allowed to run for 116 s while per-process I/O deltas were sampled every 5 s:
server listeningsession_v2session_messagesession/message/partopencode.dbfreelist_count0So the run of three starts after the offline repair moved 0 → 668 → 863 → 984 sessions, and the
third one finished and then went completely silent on writes.
Practical consequence: the "first start after this migration" is a one-off heavy operation
(~1–2 minutes of sustained I/O once the store is compact), and it has to be allowed to finish —
interrupting it makes the next start repeat a chunk of it. Doing
VACUUM+wal_checkpoint(TRUNCATE)offline before that first start shortens the waiting a lot (hereserver listeningwent from ~6 min to 5–12 s), but it does not remove the backfill itself.后续补充:离线修复结果、一处更正,以及启动时到底在写什么
1. 对原报告的一处更正
原文推测"每次启动都要重新 checkpoint 约 300 MB 的 WAL"。这条作为机制我要撤回:在这台机器
上 WAL 文件确实是 314,096,472 字节,但
PRAGMA wal_checkpoint(TRUNCATE)返回0|0|0,说明它只是一个从未被 truncate 的文件,没有任何证据表明里面有待回拷的脏页。原文里实测的部分(耗时、
I/O 体量、CPU、RSS、磁盘打满)仍然成立;"每次启动重做 300 MB checkpoint" 这个解释不成立,
真正的写入方见第 3 节。
2. 离线修复(库已收缩,启动不再是分钟级)
在 opencode 完全关闭的情况下,于同一台机器上执行:
结果:
opencode.dbfreelist_count)opencode.db-walintegrity_checkok三步合计耗时 5 分 09 秒(
VACUUM INTO77 秒,VACUUM228 秒)。对启动耗时的影响(同一命令行
opencode serve --hostname 127.0.0.1 --port <p>、同一台机器):server listening也就是说,分钟级启动已经消失(该机器唯一的数据盘是一块 4 TB SATA 机械硬盘)。
3. 仍然在写的是什么:启动时会填充 v2 表
修复并没有消除重负荷写入。修复后几次受限运行中,进程在启动后第一分钟内仍然产生
0.7–1.4 GB 文件 I/O,并且库在持续增长,而 v1 表的行数没有任何变化。
实测(修复后 → 第一次启动后 → 第二次启动后):
sessionmessagepartsession_v2session_messageopencode.db体积freelist_count观察:
session_v2/session_message(v2 形态的表)里的新行,来源是已有的 v1 数据(
session/message/part),而part的内容完全没动。session_v20 → 668 → 863,共 984 个会话),单次代价约 170–320 MB 的库增长和 0.7–1.4 GB 的 I/O。
回填因此永远跑不完,下次启动再重复一大段工作。这个库就是这样涨到 5.24 GB、72% 是空洞页的。
第一分钟内机器仍然不可用的原因。
想请教:
跑完(比如一个 CLI 命令,或"迁移完就退出"的模式),而不是依赖服务能活到跑完?
cli starting到迁移日志之间完全没有输出——能否打印进度,让用户不必猜它是不是卡住了?
4. 复现
同样的增长也可以从
PRAGMA page_count每次启动增加数万页、而PRAGMA freelist_count保持 0观察出来。
5. 更新:这个回填确实会跑完,跑完之后启动就安静了
允许第三次启动连续运行 116 秒,同时每 5 秒采样进程 I/O 增量:
server listeningsession_v2session_messagesession/message/partopencode.dbfreelist_count为 0也就是说,离线修复之后的三次启动把它推成了 0 → 668 → 863 → 984 个会话,第三次跑完,随后写入
完全静默。
实际含义:这次迁移之后的"第一次启动"是一次性的重活(库收缩后仍需 1–2 分钟持续 I/O),必须让
它跑完——中断它会让下次启动重复其中一段。在首次启动之前离线做
VACUUM+wal_checkpoint(TRUNCATE)能大幅缩短等待(本例server listening从约 6 分钟降到 5–12 秒),但并不能省掉回填本身。
Dante-dan commentedon Oct 12, 2026
I’m taking the managed-service startup retry fix. I’m checking the health-probe recovery against the existing slow-start and unresponsive-service contracts so a still-initializing child can finish within the startup window.
rorar commentedon Oct 19, 2026
Another data point for the same spawn storm, on Linux 2.0.32. Here the trigger was memory pressure, not a slow disk. Two details differ from the report above: the extra
serve --serviceprocesses did not exit, and each new process made the stall worse.Environment
latestchannel). The service ran 2.0.32. The 4 TUI clients were still the 2.0.24 binary in memory, because the update replaced the binary under them.memory.high28 GiB,memory.max32 GiB, no swap.What happened
An unrelated process in the container slowly grew to 8 GB and pushed the cgroup above
memory.high. The kernel then throttled and reclaimed continuously (memory.eventshigh: 137 million,pgmajfault: 1.46 billion). Nothing was OOM-killed, so the container stayed in this state for hours.The service boot time (
location services booted durationMs, max per hour, UTC) shows the onset:At 2026-10-19T01:29Z the running service stalled.
FileSystem.isDirandFileSystem.resolvecalls ended inInterruptError: All fibers interrupted without error, requests ran for about 128 s and ended with status 499, and the service stopped its watchers. Within 10 seconds the 4 clients started 7serve --serviceprocesses. From then on every client loggedTimed out waiting for the background service to startand started another one every 3 to 10 minutes.Counts from
opencode.logfor 2026-10-19 04:00Z to 15:59Z:serve --servicestartsManaged service port 49374 on 127.0.0.1 is already in use by another processcli starting, nothing elseThe extra processes stayed alive
When I stopped it, 66
serve --serviceprocesses were alive, 16 or 17 per client. The parent PID of each one was its TUI client. They were started over 5 hours. 12 were in state D, most of the others in state R. There were also[opencode] <defunct>zombies under the clients.Each process held only 35 to 90 MB resident, but under reclaim every one of them adds pressure and CPU time. So the storm feeds itself: the slower the service boots, the more contenders start, and the more contenders run, the slower everything gets. The host (12 cores) reached a load average of 202 with 91 % system CPU time, so other workloads on the same host stalled too.
I cannot tell from the log whether the 66 survivors are contenders that hit the port error and then failed to exit, or contenders that hung before they reached the bind. The log has no exit line for either case.
Without memory pressure the logic works. With a healthy service on 49374, a second
serve --serviceexited at once and the first one kept the port.Recovery
Killing the 4 clients, all
serve --serviceprocesses and the memory hog ended it. SIGTERM was not enough under reclaim, so SIGKILL was necessary. The run queue dropped from about 160 to 3 to 8 runnable processes within 1 minute.Suggestions for the fix in #54883
This comment was drafted together with Claude Code (Claude Opus 5.5). The numbers come from my
opencode.log, frompsand from the cgroup files, and were checked on the affected machine before posting.neriousy commentedon Oct 23, 2026
Preserving the additional reproduction from #57038: on Windows, an nthLink network stall triggered the same managed-service recovery loop, with roughly 40 changing PIDs and repeated outbound requests. Please ensure the retry work in #54883 covers this network-stall trigger as well as slow startup.