OpenCode / Memory lab

Shell jobs · 32 KiB output

Run completed shell jobs with 32768-byte outputs, using PID-tagged payloads to identify them in private heap snapshots.

Growth detected

Cycles / repetition

200

30 warm-up excluded

Heap change

+11.9 MiB

Median case, end − baseline

Adjusted growth

+39140.9 B/cycle

Positive control drift removed

Repetitions

2 / 2

Fresh case + control processes

Post-GC heap

CaseControlWarm-up
121.6129.9138.2146.5154.8058115173230MiBcontrol-1 · 0 cycles · warmup · 150.79 MiBcontrol-1 · 30 cycles · baseline · 125.68 MiBcontrol-1 · 70 cycles · measurement · 126.25 MiBcontrol-1 · 110 cycles · measurement · 126.40 MiBcontrol-1 · 150 cycles · measurement · 126.12 MiBcontrol-1 · 190 cycles · measurement · 126.67 MiBcontrol-1 · 230 cycles · measurement · 126.68 MiBcase-1 · 0 cycles · warmup · 150.79 MiBcase-1 · 30 cycles · baseline · 127.64 MiBcase-1 · 70 cycles · measurement · 133.37 MiBcase-1 · 110 cycles · measurement · 135.05 MiBcase-1 · 150 cycles · measurement · 136.69 MiBcase-1 · 190 cycles · measurement · 138.07 MiBcase-1 · 230 cycles · measurement · 139.53 MiBcase-2 · 0 cycles · warmup · 150.76 MiBcase-2 · 30 cycles · baseline · 127.58 MiBcase-2 · 70 cycles · measurement · 133.33 MiBcase-2 · 110 cycles · measurement · 135.04 MiBcase-2 · 150 cycles · measurement · 136.67 MiBcase-2 · 190 cycles · measurement · 138.03 MiBcase-2 · 230 cycles · measurement · 139.49 MiBcontrol-2 · 0 cycles · warmup · 150.73 MiBcontrol-2 · 30 cycles · baseline · 125.60 MiBcontrol-2 · 70 cycles · measurement · 126.18 MiBcontrol-2 · 110 cycles · measurement · 126.31 MiBcontrol-2 · 150 cycles · measurement · 125.99 MiBcontrol-2 · 190 cycles · measurement · 126.62 MiBcontrol-2 · 230 cycles · measurement · 126.64 MiB

Completed cycles

40 cycles per batch · 3 full GC requests per checkpoint · All measured points shown · Y-axis zoomed

Growth detected. Post-GC heap growth exceeded the control-adjusted noise allowance and continued in the later batches of every repetition. This is a leak candidate, not a root-cause finding.

Idle GC & heap evidence

Raw snapshots are private and are not served by this website. Only filtered structural findings are published.

TrialIdle secondsAfter work MiBAfter idle GC MiBSession messages
control-115126.68125.750
case-115139.53136.180
case-215139.49136.090
control-215126.64125.600

Raw idle observations. These observations are separate from the slope fit; a lower heap after idle does not by itself establish that completed outputs were released.

Verified behavior & retention hypothesis

The process-global Job service stores completed jobs, their deferred results, metadata, and output in its Map. The shipped shell/subagent executors create jobs, but Job has no removal or bounded-exit cache, unlike Shell's 25-entry cache.

control-1
Functional preflight passed (2 case + 2 control cycles).
{"completed":2,"controlCompleted":232,"progressCalls":2,"outputBytes":65536,"bytesPerCommand":32768,"sessionMessages":0,"sessionID":"ses_f9bd8f3a8ffex4jAzFsbt0oq08","firstShellID":"sh_064270c99001CHoLafvmJ94nPg","lastShellID":"sh_064270cd50018QzGmiyjEGlF5i","outputMarker":"JOBMEM_LARGE:"}
case-1
Functional preflight passed (2 case + 2 control cycles).
{"completed":232,"controlCompleted":2,"progressCalls":232,"outputBytes":7602176,"bytesPerCommand":32768,"sessionMessages":0,"sessionID":"ses_f9bd828d1ffeWvb2a0FojcBPzF","firstShellID":"sh_06427d760001GjIqYIPAYtmXvt","lastShellID":"sh_0642845a00019ExXR2GRPMpXTx","outputMarker":"JOBMEM_LARGE:"}
case-2
Functional preflight passed (2 case + 2 control cycles).
{"completed":232,"controlCompleted":2,"progressCalls":232,"outputBytes":7602176,"bytesPerCommand":32768,"sessionMessages":0,"sessionID":"ses_f9bd76fd8ffe3d96H3jcsqV3or","firstShellID":"sh_064289073001JPlZWGl0fygbk9","lastShellID":"sh_06428fedb001pMDEPhokbMbHie","outputMarker":"JOBMEM_LARGE:"}
control-2
Functional preflight passed (2 case + 2 control cycles).
{"completed":2,"controlCompleted":232,"progressCalls":2,"outputBytes":65536,"bytesPerCommand":32768,"sessionMessages":0,"sessionID":"ses_f9bd6b57affelGg1R344V8Yj2I","firstShellID":"sh_064294aba001DXyCJhAyNQq1mc","lastShellID":"sh_064294afd001HpXkgZw6cYakdo","outputMarker":"JOBMEM_LARGE:"}

Control cadence is calibrated from two real preflight cycles in each process and recorded as controlCadenceMs. Both arms get at least 20 seconds of warm-up/settling before the baseline. This approximately matches elapsed time, not every internal allocation or polling read.

Source inspected at 4772b6a3e8; this is the investigation reference, not a claim about the binary’s build commit.

Method & run details

One fixed session and one inspector transform remain. Commands finish before measurement; the fixture retains neither results nor a growing ID list. Session context remains empty.

Control. Run the same executable and output through a plain subprocess, without OpenCode's shell/job bookkeeping. Both arms are cadence-matched and warmed beyond the shell service's 25-exit cache.

Metric: target process.memoryUsage().heapUsed after Bun.gc(true). Warm-up excluded. Theil–Sen slope; later-half slope must remain positive. Subtract positive control drift only. A growing control, large baseline drift, or a noise allowance above max(1 MiB, 5% of baseline) that prevents detecting a trend makes attribution inconclusive. Net growth and slope × cycles must both exceed max(128 KiB, 6 × combined robust residual noise). Require agreement across at least two fresh-process repetitions. Heuristic, not a significance test.

OpenCode
0.0.0-dev-18911 · dev channel · installed binary
Drive
1.4.4 · installed package
Runtime
Bun 1.4.0 · linux / x64
Isolation
Private server + file-backed database. TUI closed before warm-up. Measurement plugin remains loaded; no object-level instrumentation.
Checkpoints
Case-specific cleanup checks pass before GC; 300 ms settling allowance. This is not a global background-work barrier.
Snapshots
Disabled. Use --snapshots for a diagnostic rerun.
Run
2026-09-02T22-04-32-353Z-59f2dc · 2026-09-02T22:04:32.354Z
cd /root/projects/opencode-memory-lab && bun run run --case shell-jobs-large --warmup 30 --batches 5 --batch-size 40 --repetitions 2 --settle-ms 300 --warmup-ms 20000 --idle-ms 15000
RepetitionCase Δ MiBControl Δ MiBAdjusted B/cycleGate KiB
111.901.0039216.22207
211.911.0439065.52185
Process RSS

Includes native allocations and allocator behavior. Not used to classify JS heap growth.

227.1244.0260.8277.6294.5058115173230MiBcontrol-1 · 0 cycles · warmup · 266.67 MiBcontrol-1 · 30 cycles · baseline · 247.77 MiBcontrol-1 · 70 cycles · measurement · 236.09 MiBcontrol-1 · 110 cycles · measurement · 237.13 MiBcontrol-1 · 150 cycles · measurement · 235.30 MiBcontrol-1 · 190 cycles · measurement · 237.18 MiBcontrol-1 · 230 cycles · measurement · 236.30 MiBcase-1 · 0 cycles · warmup · 276.39 MiBcase-1 · 30 cycles · baseline · 257.32 MiBcase-1 · 70 cycles · measurement · 256.40 MiBcase-1 · 110 cycles · measurement · 271.95 MiBcase-1 · 150 cycles · measurement · 274.23 MiBcase-1 · 190 cycles · measurement · 286.32 MiBcase-1 · 230 cycles · measurement · 282.63 MiBcase-2 · 0 cycles · warmup · 277.70 MiBcase-2 · 30 cycles · baseline · 255.89 MiBcase-2 · 70 cycles · measurement · 254.83 MiBcase-2 · 110 cycles · measurement · 265.64 MiBcase-2 · 150 cycles · measurement · 269.63 MiBcase-2 · 190 cycles · measurement · 277.14 MiBcase-2 · 230 cycles · measurement · 280.78 MiBcontrol-2 · 0 cycles · warmup · 270.71 MiBcontrol-2 · 30 cycles · baseline · 256.10 MiBcontrol-2 · 70 cycles · measurement · 244.38 MiBcontrol-2 · 110 cycles · measurement · 244.93 MiBcontrol-2 · 150 cycles · measurement · 244.33 MiBcontrol-2 · 190 cycles · measurement · 243.55 MiBcontrol-2 · 230 cycles · measurement · 243.69 MiB
Measurements · 28 checkpoints
TrialPhaseCyclesHeap MiBRSS MiBPIDGC ms
control-1warmup0150.79266.671210694.8
control-1baseline30125.68247.771210684.6
control-1measurement70126.25236.091210676.4
control-1measurement110126.40237.131210670.4
control-1measurement150126.12235.301210674.3
control-1measurement190126.67237.181210667.6
control-1measurement230126.68236.3012106110.8
case-1warmup0150.79276.391382499.5
case-1baseline30127.64257.321382479.7
case-1measurement70133.37256.401382469.2
case-1measurement110135.05271.951382474.3
case-1measurement150136.69274.231382489.5
case-1measurement190138.07286.3213824117.1
case-1measurement230139.53282.631382472.4
case-2warmup0150.76277.701534192.9
case-2baseline30127.58255.891534184.6
case-2measurement70133.33254.831534180.3
case-2measurement110135.04265.641534193.0
case-2measurement150136.67269.6315341133.8
case-2measurement190138.03277.141534176.9
case-2measurement230139.49280.781534173.4
control-2warmup0150.73270.711686090.3
control-2baseline30125.60256.101686083.8
control-2measurement70126.18244.381686074.9
control-2measurement110126.31244.931686079.0
control-2measurement150125.99244.331686069.2
control-2measurement190126.62243.551686080.2
control-2measurement230126.64243.691686065.8