Skip to content

fix(opencode): reduce memory allocations in read tool#13676

Closed
SeanThomasWilliams wants to merge 12 commits intoanomalyco:devfrom
SeanThomasWilliams:fix/memory-read-tool-fragmentation
Closed

fix(opencode): reduce memory allocations in read tool#13676
SeanThomasWilliams wants to merge 12 commits intoanomalyco:devfrom
SeanThomasWilliams:fix/memory-read-tool-fragmentation

Conversation

@SeanThomasWilliams
Copy link

@SeanThomasWilliams SeanThomasWilliams commented Feb 15, 2026

Fixes #13669

Reduce transient memory allocations in ReadTool:

  • Bounded file.slice(0, estimate).text() instead of file.text() for text reads (issue item 1)
  • Binary detection reads only first 4KB via file.slice(0, 4096).arrayBuffer() (issue item 2)
  • Async readdir for missing-file suggestions

Item 3 from the issue (image/PDF base64 size guard) is not addressed here — capping inline images would be a feature regression since all sizes currently work. That can be revisited separately if needed.

Tests

$ cd packages/opencode && bun test test/tool/read.test.ts --timeout 30000

bun test v1.2.20 (6ad208bc)

 33 pass
 0 fail
 59 expect() calls
Ran 33 tests across 1 file. [2.06s]

Memory verification

100MB text file read, peak RSS measured by polling the child process VmRSS.
The opencode launcher spawns a native binary child, so pgrep -P finds the actual process to sample.

STOCK=$(npm root -g)/opencode-ai/node_modules/opencode-linux-x64/bin/opencode
PATCHED=packages/opencode/dist/opencode-linux-x64/bin/opencode

# Generate 100MB fixture
(yes "line lorem ipsum dolor sit amet" || true) 2>/dev/null \
  | head -c 104857600 > /tmp/large.txt

# Measure one run (repeat for each binary)
measure() {
  OPENCODE_BIN_PATH="$1" opencode run \
    "Use the read tool on /tmp/large.txt with offset 1 and limit 2000. Reply OK." \
    >/dev/null 2>/dev/null &
  local parent=$!
  local child="" peak=0

  # Wait for native binary child to spawn
  for i in $(seq 1 40); do
    child=$(pgrep -P $parent 2>/dev/null | head -1)
    [ -n "$child" ] && break
    sleep 0.25
  done

  # Poll VmRSS every 50ms
  while kill -0 $parent 2>/dev/null; do
    local rss=$(awk '/^VmRSS/{print $2}' /proc/${child}/status 2>/dev/null)
    [ "${rss:-0}" -gt "$peak" ] && peak=$rss
    sleep 0.05
  done
  wait $parent 2>/dev/null
  echo "$peak"
}

echo "stock:   $(measure $STOCK) KB"
echo "patched: $(measure $PATCHED) KB"
rm /tmp/large.txt

Results (3 runs each):

label      run  peak_rss_kb
stock        1       590580
stock        2       602804
stock        3       600364
patched      1       394936
patched      2       387172
patched      3       386440

stock   mean=584 MB  stddev=6.3 MB
patched mean=380 MB  stddev=4.6 MB
delta   -35% peak RSS

Small file control (100 lines) — no regression:

stock-small   peak_rss = 356 MB
patched-small peak_rss = 378 MB  (within noise)

Edge cases verified

Case Result
Empty file (0 bytes) Reads successfully, reports 1 blank line
Single 5MB line (no newlines) Returns truncated first line
Offset past EOF (offset=9999 on 2-line file) Error: Offset 9999 is out of range
Binary file (random bytes) Error: Cannot read binary file
Unicode/multibyte (CJK, emoji, accents) All characters preserved correctly

@SeanThomasWilliams SeanThomasWilliams marked this pull request as draft February 15, 2026 04:52
@SeanThomasWilliams SeanThomasWilliams changed the title fix(tool): reduce memory allocations in ReadTool perf(tool): reduce memory allocations in ReadTool Feb 15, 2026
@github-actions
Copy link
Contributor

Hey! Your PR title perf(tool): reduce memory allocations in ReadTool doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@SeanThomasWilliams SeanThomasWilliams changed the title perf(tool): reduce memory allocations in ReadTool perf: reduce memory allocations in read tool Feb 15, 2026
@SeanThomasWilliams SeanThomasWilliams changed the title perf: reduce memory allocations in read tool fix(opencode): reduce memory allocations in read tool Feb 15, 2026
@SeanThomasWilliams
Copy link
Author

Superseded by #14009 and #14027 which landed on dev with equivalent fixes (streaming text reads, bounded binary detection, async readdir).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ReadTool allocates entire file contents for bounded operations (binary check, text read, base64)

1 participant