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
Hooray, will contribute what I can. Curious to learn if you have any tips for avoiding the false diagnoses from LLMs. Why do they struggle so much, and is it fixable?
Reacted by Tomáš Hübelbauer, Ian Schmitz, Nikolai Grlica, Muhammad Aziz Prasetyo and Vihanga
Hey @thdxr , the particular problem I am running into is not while running opencode with the terminal (#17047 in this issue), but rather, when running it in server mode. Any suggested method to help you collect evidence for memory leaks while running it on server mode?
Also, I think the error that I am mentioning here appears to have a clear one liner fix that avoids RangeErrors for tool calls on a long running server. (I am currently running a fork that serves thousands of requests per day, and without this fix it crashes with RangeErrors on any tool call after 2 hours of running): #16952
I debugged extensively and added additional logging to tools to be able to understand exactly what was causing the stack overflow type error. They all came from this exact line:
const toolInfo = init instanceof Function ? await init(initCtx) : init which reuses the same tool definition object for object defined tools, so each init() call wraps the previously wrapped execute and accumulates wrapper closures over time.
I'm running the client with opencode attach and the "heap snapshot" command writes the snapshots to undefined and find / -type f -name "server.heapsnapshot" cannot find it either.
I'm not really sure my issue would have shown up in the snapshot anyway, because it is not so much a memory leak inside opencode itself, but mainly the fact that it starts a playwright MCP server per unique directory/worktree, and at a cost of 98M per instance it can quickly add up.
I have 8 .heapsnapshot files captured from 3 different processes at various RSS levels (2.5GB to 11GB). Will upload to the Dropbox link.
serve-early-359MB.heapsnapshot — opencode serve at ~2.5GB RSS
serve-peak-1.6GB.heapsnapshot — same serve at ~11GB RSS
tui-299MB.heapsnapshot — TUI session (different process, same leak)
What we found
JS heap (5-8GB): FileDiff.before/after fields from snapshot.diffFull() storing entire file contents as strings. 22 copies of a 20MB JSON file = 440MB from one file alone. summary_diffs column in SessionTable loads these into memory on session resume.
Native memory (140GB+ beyond JS heap): This is the bigger issue. Using memleak-bpfcc with bun-linux-x64-profile for symbol resolution, we captured the allocation stack:
11.5GB in 55 allocations (~210MB each) via bmalloc's pas_large_heap_try_allocate_user_allocation that never get freed. This is the known bmalloc slab retention bug (oven-sh/bun#28318).
I captured paired TUI and server heap snapshots from OpenCode 1.18.23 on Linux x86_64. The terminal client was running under tmux for about seven hours with concurrent subagent work during the session.
Before capture, the OpenCode process used 2.67 GiB RSS and about 84% CPU. /proc reported approximately 2.1 GiB of private anonymous memory before snapshot generation. The main thread used about 29% CPU, seven HeapHelper threads used roughly 6.8% each, and one worker used about 6%. This looked like sustained garbage collection rather than file-backed database memory.
The paired snapshots differ substantially:
Snapshot
File size
Nodes
Edges
TUI
707,391,772 bytes
10,857,279
35,670,487
Server
149,527,598 bytes
2,407,682
7,374,399
The TUI heap contains 6,380,387 objects, 3,196,177 closures, and 3,306,738 arrays. One minified closure named sJ has 969,251 live instances and 93,194,866 bytes of self size. Direct incoming references include 215,639 object properties named fn, about 153,000 lexical-context references each under two minified names, and 60,364 array elements. Other direct references use fields found in message and part state, including value, type, time, metadata, input, output, state, text, tool, and sessionID.
The server heap does not contain the same sJ population. Its largest groups are generic objects, functions, lexical environments, arrays, and maps. This paired result localizes the dominant live-object population to the TUI rather than an MCP child or file-backed SQLite pages. I cannot map sJ to an unminified source symbol without the release build's source map.
The resumed session had 11,199 persisted event rows containing about 113 MiB of serialized event payload, 404 message rows, and 2,161 part rows. Restarting OpenCode reduced RSS from 2.67 GiB to about 846 MiB and removed the sustained HeapHelper load. The resumed event-heavy session still had a high baseline, but the restart reclaimed about 1.8 GiB.
I have both raw snapshots and can submit them through the upload channel linked in this issue. Their SHA-256 hashes are:
@thdxr This is still an issue. Two opencode instances with <200k tokens uses 800 megabytes of memory each, whereas claude code needs <400 megabytes of memory.
the majority of memory issues have been fixed in opencode2 which is coming out in the following 2 weeks. you can use it now here: http://opencode.ai/v2
v2.0.18 TUI: 115.6 GB RSS after ~8.5h, session content only 1.1 MB — system-wide OOM
Debian 13, X11, local llama.cpp model (27B), agent=build, 12–14 plugins. TUI launched in tmux pane 2026-09-28 23:58, OOM-killed 2026-09-29 08:55. Kernel: task=opencode, total-vm: 152025376kB, anon-rss: 121119400kB. Cgroup peak 116G
RAM / 4.9G swap; total CPU 12m32s (~2% avg). Session: 195 messages, ~142k input / 142k output tokens, ~1.1 MB stored content (largest message 70 KB). The global OOM also killed the KDE Plasma shell via systemd OOMPolicy=stop.
Happened on the latest release, so it persists in v2.
Reacted by Oskars Germovs, Sammy Guergachi, Samuel Huang, 叶子 and Ray Tian
opencode2 has a bug that when you resize the tui, it will glitch out and cause a memory leaks to fill 16GB of ram (+16Gb of swap) in 20 seconds . its really bad because its caused by the server and not the tui somehow.
opencode2 has a bug that when you resize the tui, it will glitch out and cause a memory leaks to fill 16GB of ram (+16Gb of swap) in 20 seconds . its really bad because its caused by the server and not the tui somehow.
A fix for this is in our v2 branch and will go out next release
Activity
sjawhar commentedon Apr 2, 2026
Hooray, will contribute what I can. Curious to learn if you have any tips for avoiding the false diagnoses from LLMs. Why do they struggle so much, and is it fixable?
heimoshuiyu commentedon Apr 2, 2026
How to "write heap snapshot" in web mode?
jpcarranza94 commentedon Apr 2, 2026
Hey @thdxr , the particular problem I am running into is not while running opencode with the terminal (#17047 in this issue), but rather, when running it in server mode. Any suggested method to help you collect evidence for memory leaks while running it on server mode?
Also, I think the error that I am mentioning here appears to have a clear one liner fix that avoids RangeErrors for tool calls on a long running server. (I am currently running a fork that serves thousands of requests per day, and without this fix it crashes with RangeErrors on any tool call after 2 hours of running): #16952
I debugged extensively and added additional logging to tools to be able to understand exactly what was causing the stack overflow type error. They all came from this exact line:
const toolInfo = init instanceof Function ? await init(initCtx) : initwhich reuses the same tool definition object for object defined tools, so each init() call wraps the previously wrapped execute and accumulates wrapper closures over time.Happy to help provide more logs/heap snapshots.
thdxr commentedon Apr 3, 2026
@jpcarranza94 great find - merging that
thdxr commentedon Apr 3, 2026
next release will have a flag for auto snapshots - added stuff in instructions
Sheraff commentedon Apr 3, 2026
I'm running the client with
opencode attachand the "heap snapshot" command writes the snapshots toundefinedandfind / -type f -name "server.heapsnapshot"cannot find it either.I'm not really sure my issue would have shown up in the snapshot anyway, because it is not so much a memory leak inside
opencodeitself, but mainly the fact that it starts a playwright MCP server per unique directory/worktree, and at a cost of 98M per instance it can quickly add up.Maybe some MCPs could be configured to be global?
CarloWood commentedon Apr 3, 2026
If anyone can help me to reproduce this (any leak) on my Arch/linux box, then I can probably help finding where that comes from.
sjawhar commentedon Apr 4, 2026
Heap snapshots + native memory profiling data
Snapshots
I have 8
.heapsnapshotfiles captured from 3 different processes at various RSS levels (2.5GB to 11GB). Will upload to the Dropbox link.serve-early-359MB.heapsnapshot— opencode serve at ~2.5GB RSSserve-peak-1.6GB.heapsnapshot— same serve at ~11GB RSStui-299MB.heapsnapshot— TUI session (different process, same leak)What we found
JS heap (5-8GB):
FileDiff.before/afterfields fromsnapshot.diffFull()storing entire file contents as strings. 22 copies of a 20MB JSON file = 440MB from one file alone.summary_diffscolumn in SessionTable loads these into memory on session resume.Native memory (140GB+ beyond JS heap): This is the bigger issue. Using
memleak-bpfccwithbun-linux-x64-profilefor symbol resolution, we captured the allocation stack:11.5GB in 55 allocations (~210MB each) via bmalloc's
pas_large_heap_try_allocate_user_allocationthat never get freed. This is the known bmalloc slab retention bug (oven-sh/bun#28318).Scenario
opencode serve --port 13381handling 100 sessions across 10 project directories (Legion worker fleet)Data in Dropbox upload
heap-analysis.txt— programmatic analysis of snapshot 1 (top types by retained size)heap-diff.txt— diff between snapshot 1 and 2 showing what grewmemleak-bpfcctraces with fully resolved native stacksbpftracemmap syscall tracesAutomatic snapshot flow
Used
OPENCODE_AUTO_HEAP_SNAPSHOT=1on the serve. TUI snapshots captured viakill -USR1.Uploading files now.
sjawhar commentedon Apr 4, 2026
Heap snapshots and profiling data uploaded here (zstd-compressed, decompress with
zstd -d <file>.zst):https://github.com/sjawhar/opencode/releases/tag/memory-leak-data
Contents:
serve-early-359MB.heapsnapshot.zst(71MB) — serve at ~2.5GB RSSserve-peak-1.6GB.heapsnapshot.zst(172MB) — same serve at ~11GB RSStui-299MB.heapsnapshot.zst(113MB) — TUI sessionheap-analysis.txt— programmatic type/retained-size breakdownheap-diff.txt— what grew between the two serve snapshotsmemleak-20260404-030902.log— memleak-bpfcc native allocation tracesbpftrace-mmap-20260404-030856.log— mmap syscall tracesmemory-telemetry-stderr.log— RSS/heap/smaps timeline140 remaining items
freaksdotcom commentedon Aug 27, 2026
I captured paired TUI and server heap snapshots from OpenCode 1.18.23 on Linux x86_64. The terminal client was running under tmux for about seven hours with concurrent subagent work during the session.
Before capture, the OpenCode process used 2.67 GiB RSS and about 84% CPU.
/procreported approximately 2.1 GiB of private anonymous memory before snapshot generation. The main thread used about 29% CPU, sevenHeapHelperthreads used roughly 6.8% each, and one worker used about 6%. This looked like sustained garbage collection rather than file-backed database memory.The paired snapshots differ substantially:
The TUI heap contains 6,380,387 objects, 3,196,177 closures, and 3,306,738 arrays. One minified closure named
sJhas 969,251 live instances and 93,194,866 bytes of self size. Direct incoming references include 215,639 object properties namedfn, about 153,000 lexical-context references each under two minified names, and 60,364 array elements. Other direct references use fields found in message and part state, includingvalue,type,time,metadata,input,output,state,text,tool, andsessionID.The server heap does not contain the same
sJpopulation. Its largest groups are generic objects, functions, lexical environments, arrays, and maps. This paired result localizes the dominant live-object population to the TUI rather than an MCP child or file-backed SQLite pages. I cannot mapsJto an unminified source symbol without the release build's source map.The resumed session had 11,199 persisted event rows containing about 113 MiB of serialized event payload, 404 message rows, and 2,161 part rows. Restarting OpenCode reduced RSS from 2.67 GiB to about 846 MiB and removed the sustained
HeapHelperload. The resumed event-heavy session still had a high baseline, but the restart reclaimed about 1.8 GiB.I have both raw snapshots and can submit them through the upload channel linked in this issue. Their SHA-256 hashes are:
NoahBPeterson commentedon Sep 4, 2026
@thdxr This is still an issue. Two opencode instances with <200k tokens uses 800 megabytes of memory each, whereas claude code needs <400 megabytes of memory.
Your dropbox links are down, too.
jeremyakers commentedon Sep 5, 2026
Opencode just crashed with this:
max-flizpay commentedon Sep 8, 2026
What a joke, its been 7 months and we are still nowhere.
Opencode has lost my trust
VihangaFTW commentedon Sep 8, 2026
thdxr commentedon Sep 8, 2026
the majority of memory issues have been fixed in opencode2 which is coming out in the following 2 weeks. you can use it now here: http://opencode.ai/v2
thdxr commentedon Sep 8, 2026
closing this issue and we'll track v2 memory issues as individual issues
Sewer56 commentedon Sep 26, 2026
My first experience of V2 is 80+GB RAM usage and OOM 😅
Which is how I got here.
On the other hand, V2 is great, especially with how plugin-extensible it is.
Faks commentedon Sep 29, 2026
Hi, seems your fix did not fix memory leak...
v2.0.18 TUI: 115.6 GB RSS after ~8.5h, session content only 1.1 MB — system-wide OOM
Debian 13, X11, local llama.cpp model (27B), agent=build, 12–14 plugins. TUI launched in tmux pane 2026-09-28 23:58, OOM-killed 2026-09-29 08:55. Kernel: task=opencode, total-vm: 152025376kB, anon-rss: 121119400kB. Cgroup peak 116G
RAM / 4.9G swap; total CPU 12m32s (~2% avg). Session: 195 messages, ~142k input / 142k output tokens, ~1.1 MB stored content (largest message 70 KB). The global OOM also killed the KDE Plasma shell via systemd OOMPolicy=stop.
Happened on the latest release, so it persists in v2.
Sporknife commentedon Sep 29, 2026
opencode2 has a bug that when you resize the tui, it will glitch out and cause a memory leaks to fill 16GB of ram (+16Gb of swap) in 20 seconds . its really bad because its caused by the server and not the tui somehow.
simonklee commentedon Sep 30, 2026
A fix for this is in our v2 branch and will go out next release
Sporknife commentedon Sep 30, 2026
@simonklee thank you.
Abdur-rahmaanJ commentedon Oct 12, 2026
CLOSED???