Skip to content

opencode-cli serve CPU saturated (200%+) by repeated full-patch generation — only workaround is disabling snapshot #21699

Closed as not planned

Description

@cpkt9762

Description

When using OpenCode Desktop App (v1.4.0), the bundled opencode-cli serve backend process consistently exceeds 200% CPU during active agent sessions. The only effective workaround is setting "snapshot": false in config, which disables session change tracking and file revert/undo — a significant feature trade-off.

Root cause (CPU profiled):

  • Top frame: vcs.ts:63 accounts for ~65% of total sampled time
  • Dominant stack: execEditLength ← structuredPatch ← patch3[vcs.ts:53] ← (anonymous)[vcs.ts:63]
  • summarize() generates full unified patches on every file event when it only needs summary statistics

Environment:

Item Detail
Machine Apple M4 Max, 128 GB RAM, 4 TB SSD
OS macOS 26.2 (Build 25C56), arm64
Client OpenCode Desktop App v1.4.0
Backend opencode-cli serve (bundled with Desktop App)
Project Large monorepo (~51,000 files excl. node_modules/.git, 19 packages)

Suggested fixes (by priority):

  1. Separate summary stats from full patch generation — summarize() only needs additions/deletions/files counts, which git diff --numstat provides cheaply. Generate actual patch strings only on demand when the user expands a specific file in the review UI.
  2. Debounce + coalesce refreshVcs() — use a dirty-flag + debounce (300–1000 ms) so a burst of file writes triggers only one diff instead of clearing in-flight dedup state on every event.
  3. Use git-native patch output instead of JS-side structuredPatch() — moves the O(N·D) algorithm out of the Node event loop entirely.
  4. Cache patches by file content hash — skip re-diffing files whose before/after content hasn't changed.

Related: #21470, #19466

Plugins

oh-my-openagent (local)
[email protected]

OpenCode version

1.4.0 (Desktop App, bundled opencode-cli serve)

Steps to reproduce

  1. Open a large project with OpenCode Desktop App (keep the Changes/Review panel visible)
  2. Start an agent session that edits files across multiple steps
  3. Observe opencode-cli serve process CPU climbing above 200% as the session progresses
  4. Set "snapshot": false in config to confirm it stops — this is the only workaround, but disables session change tracking

Screenshot and/or share link

CPU profile files are saved at ~/.local/share/opencode/log/cpu-*.cpuprofile and can be loaded in Chrome DevTools Performance tab.

Operating System

macOS 26.2 (Build 25C56), Apple M4 Max, 128 GB RAM, 4 TB SSD

Terminal

OpenCode Desktop App v1.4.0

Activity

  1. changed the title [-]perf: opencode-cli server CPU saturated (200%+) by repeated full-patch generation — only workaround is disabling snapshot[/-] [+]opencode-cli serve CPU saturated (200%+) by repeated full-patch generation — only workaround is disabling snapshot[/+] on Apr 10, 2026
  2. removed
    bugSomething isn't working
    on May 3, 2026
  3. ChrisJamesHassell commented on May 5, 2026

    @ChrisJamesHassell

    Adding some evidence here from a different angle that might shift the priority of fix # 2 (debounce + coalesce refreshVcs()) above fix # 1 (separate summary stats from full patches).

    I was hitting the same 100%+ CPU symptom on a large monorepo, but when I looked at Activity Monitor while it was happening, the split was 89% system time vs 11% user time:

    Activity Monitor: 100% CPU, all cores, 89% system / 11% user, load avg 172.63, six concurrent git processes

    If structuredPatch() were the dominant cost, I'd expect that to show up as user time. 89% system time points at the kernel doing fork/exec/wait/SIGCHLD work. The cost is spawning git processes, not running the JS-side patch builder.

    Looking at the process tree at the same moment, I had 53+ concurrent git status --porcelain=v1 --untracked-files=all --no-renames -z -- . targeting the same worktree

    So in this case the bottleneck is the unbounded fan-out itself. Even with structuredPatch made cheap, an unbounded number of git status --untracked-files=all invocations stacking faster than they finish on a large repo is enough on its own to peg CPU.

    (Filed the zombie-reaping side of this separately at #25883 since it seems like a distinct bug worth its own thread. 4,978 <defunct> children persisting for several minutes after activity stops.)

  4. github-actions commented on Jul 5, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions