Skip to content

fix(terminal): cap VirtualTerminal scrollback to bound memory and render cost - #387

Open
RonenMars wants to merge 1 commit into
perf/freeze-hidden-session-screensfrom
perf/cap-virtualterminal-scrollback
Open

fix(terminal): cap VirtualTerminal scrollback to bound memory and render cost#387
RonenMars wants to merge 1 commit into
perf/freeze-hidden-session-screensfrom
perf/cap-virtualterminal-scrollback

Conversation

@RonenMars

Copy link
Copy Markdown
Owner

Problem

VirtualTerminal grew its internal grid without bound for an append-only session.
Only the rendered copy was capped (getLines().slice(-maxLines)), so getLines() stayed an O(total-lines) scan run on every terminal_output frame, and memory grew with the full transcript.
Combined with retained background session screens (see the stacked base PR) this compounded the cumulative slowdown after several sessions.

Fix

Trim the oldest rows once the grid passes a 10k cap and shift the cursor (this.row) by the same amount so absolute row addressing stays correct.
The cap sits well above any TUI screen height, so absolute cursor positioning never triggers the trim; only unbounded append-growth does.

Tests

Added a scrollback-cap case to __tests__/unit/services/virtual-terminal.test.ts: an append-only stream past the cap stays bounded, keeps the newest line, and drops the oldest.
Full VirtualTerminal suite green (220 tests).

Compatibility

Mobile-only, internal to the terminal emulator.
No server, API, or WS-contract changes.

Stacking

This PR is based on perf/freeze-hidden-session-screens (#386), so its diff shows only the VirtualTerminal change.
Merge #386 first, then this one, in integration-branch order.

…der cost

An append-only session grew the VirtualTerminal grid without limit; only the rendered copy was capped (slice(-maxLines)), so getLines() stayed an O(total-lines) scan on every terminal_output frame.
Combined with retained background session screens this compounded the cumulative slowdown.
Trim the oldest rows past a 10k cap and shift the cursor to match, so memory and per-frame cost stay bounded regardless of transcript length.
RonenMars added a commit that referenced this pull request Jul 23, 2026
…kip-ci]

Record PRs #385, #386 and #387 as a separate follow-up chain in the land-open-prs runbook.
#385 and #386 target main independently; #387 is stacked on #386 and must be rebased onto main before merging.

[skip-ci]
RonenMars added a commit that referenced this pull request Jul 24, 2026
…kip-ci]

Record PRs #385, #386 and #387 as a separate follow-up chain in the land-open-prs runbook.
#385 and #386 target main independently; #387 is stacked on #386 and must be rebased onto main before merging.

[skip-ci]
RonenMars added a commit that referenced this pull request Jul 26, 2026
…kip-ci]

Record PRs #385, #386 and #387 as a separate follow-up chain in the land-open-prs runbook.
#385 and #386 target main independently; #387 is stacked on #386 and must be rebased onto main before merging.

[skip-ci]
RonenMars added a commit that referenced this pull request Jul 28, 2026
…kip-ci]

Record PRs #385, #386 and #387 as a separate follow-up chain in the land-open-prs runbook.
#385 and #386 target main independently; #387 is stacked on #386 and must be rebased onto main before merging.

[skip-ci]
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.

1 participant