Skip to content

perf: ImageAddon defaults to 128 MB storage per pane — multi-pane sessions can hit GBs #565

Description

@Axelj00

Problem

`src/pane-webgl.ts:115` constructs the xterm.js `ImageAddon` with no options:

```ts
const img = new ImageAddon();
```

Per the addon's type definitions (`@xterm/addon-image/typings/addon-image.d.ts:51`):

`storageLimit` — Storage limit in MB. The storage implements a FIFO cache removing old images, when the limit gets hit. Default is 128 MB.

That's 128 MB of image bitmap retention per pane. The user's mental model of a 4-tab × 2-pane workspace running Claude Code that occasionally renders screenshots (sixel / iTerm2 inline images) suddenly tops out at 8 × 128 MB = 1 GB just for image storage, on top of scrollback + Chromium baseline + Rust process.

The storage is FIFO-evicted within the 128 MB cap, but the cap itself never shrinks, and nothing tells the user about it. A single 100 MB screenshot pins the pane at 100 MB forever (until tab close / pane dispose deactivates the addon).

Why this matters now

Agent workflows have grown to include image output:

  • Claude Code with `--allow-screenshots` produces base64 PNGs via OSC 1337 (iTerm2 IIP).
  • Tools that pipe image previews (`imgcat`, `viu`, sixel emitters from `gnuplot` / `mpv` / `yt-dlp`).
  • Agent screenshots committed to scrollback as inline images.

ClawTerm advertises itself as the terminal for running many AI agents. The default 128 MB cap multiplied by typical pane counts is a real cost the user pays without ever opting in.

Proposal

Three options, each shipping independently:

1. Lower the default cap (cheapest, behavior change)

```ts
const img = new ImageAddon({ storageLimit: 32 });
```

32 MB per pane is still 8 × a single moderate screenshot, but caps the worst-case at ~256 MB across an 8-pane workspace. Trade-off: long agent sessions that produce many screenshots will see older ones replaced with the placeholder glyph sooner.

2. Config-driven (gives users a knob)

Add `pane.imageStorageLimitMb: number` (default 32) to `config-types.ts`. Users running image-heavy workflows can bump it; users running text-only agents can drop it to 0 (effectively disable).

3. "Reset images" command (manual escape hatch)

Surface `imageAddon.reset()` via the command palette and/or right-click pane menu. Lets a user reclaim the memory without closing the pane or tab.

Suggest (1) + (3) for v1 — lower the default and add a manual reset. (2) is the right shape long-term but a config field is more surface area than this needs to start.

Verification path

Before merging the default change, do a memory comparison:

  1. Open Activity Monitor → ClawTerm RSS at startup.
  2. Open 4 tabs, run a Claude session in each that includes `imgcat ~/Downloads/test-screenshot-5mb.png`.
  3. Note the RSS plateau.
  4. Apply the storageLimit change, repeat.

If the plateau shrinks proportionally to the cap, the fix is working as intended.

References

Out of scope

  • Disposing ImageAddon on tab hide (analogous to scrollback compaction). Would force re-decode of every image on tab return, breaking the "click around panes" UX. The cap-then-evict approach trades less obtrusively.
  • Replacing ImageAddon entirely. xterm.js has no built-in image support; the addon is the only practical option.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    memory-leakResource leaks and cleanup issuesperformancePerformance improvementspriority: highShould be addressed soon

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions