Skip to content

serve: idle service burns 20-45% CPU in silent bursts from launch; memory creeps #42299

Description

@kahlos

Summary

A freshly launched, completely idle serve service (and its TUI client) burns 20–45% CPU in silent periodic bursts from launch onward, with no log output during the bursts and continuous SQLite WAL writes. RSS creeps upward (~2% of RAM in 6 minutes). Reproduces on every launch; not caused by autoupdate, sessions, activity, or terminal.

Environment

  • opencode version: 0.0.0-next-17403 (also reproduced on 17364)
  • OS: macOS 26.5.2 (Darwin 25.5.0, arm64)
  • Terminal: ghostty 1.3.1 (TERM=xterm-ghostty); also reproduced inside screen (TERM=screen)
  • Shell: /bin/zsh
  • Install/channel: npm, next channel (nightly, autoupdate was enabled)
  • Active plugins: local.notify at ~/.config/opencode/plugins/notify.ts (event-driven osascript notifications; inert when idle — not ruled out by bisect)

Reproduction

  1. Launch opencode2 (TUI) on a clean config — or fully detached: screen -dmS opencode2 opencode2
  2. Leave it completely idle (no session open, no input)
  3. Watch CPU for 5+ minutes: ps -o pid,%cpu,%mem,etime,time -p <tui-pid> <service-pid>

Observed on a fresh detached pair (screen TUI + serve --service, no session ever opened, autoupdate disabled):

time since launch service %CPU idle TUI %CPU
0:20 23.2 21.3
0:50 0.8 14.1
1:20 41.9 16.8
2:00 43.5 23.7
2:30 43.0 15.8
3:30 0.3 0.3
~4:30 37.1 14.1
7:35 47.9 16.1

The bursts are cyclic (roughly 2 minutes on, 1–2 minutes off) and persist indefinitely — the original pair ran 1h47m without settling.

Expected Behavior

An idle opencode service should idle: ~0% CPU, no sustained WAL growth, stable RSS.

Actual Behavior

  • Service + TUI burn 20–45% CPU in silent bursts from launch, indefinitely
  • During bursts: nothing is logged (log tail frozen), but opencode.db-wal is written continuously (mtime tracks the burst)
  • Service RSS grows steadily during bursts (~3.9% → 6.1% of RAM in 6 minutes)
  • sample during a burst shows the service main thread in the event-loop dispatch with only ~78% of samples in kevent64 (i.e. ~22% non-idle), and Bun Pool threads non-idle — no hard spin, but constant wake-up/do-work churn. JSC threads show cond_wait leaves (not a spin)
  • On 17364 one instance degraded into a hard spin (98.8% CPU, ignored SIGTERM, required SIGKILL)

Additional Context

  • "autoupdate": false does NOT fix the bursts (measured on the fresh pair above)
  • With autoupdate enabled (the default on next), the service additionally runs an update check every ~10 min and a catalog.updated reload across all open project directories every ~5 min, each request taking 4–6 s server-side (http.span=4000000+). 626 update checks were logged over ~2 weeks of log. Found nightlies trigger npm install into the config dir, which cascades into 100–180 event bursts (config/agent/command/catalog.updated). This keeps service+TUI at 30–50% CPU permanently
  • Reproduced across two services (17364 and 17403) and two TUIs, including one with zero sessions
  • Full probe timeline: /tmp/opencode_cpu_probe.log; service stack during burst: /tmp/sample25141.txt; earlier TUI sample: /tmp/sample2.txt (available on request)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions