perf(terminal): cap write-flush rate at ~30 fps - #64
Merged
Conversation
…nt cost Measured 2026-06-12: while a Claude session streams, the renderer's Compositor thread burns 40-60% of a core flushing terminal writes on every animation frame. A 33 ms minimum interval between flushes halves paint work and doubles parse-batch size; worst-case added display latency is one frame (~33 ms), imperceptible for streaming text. The throttle timer reuses buf.timerId so the existing teardown paths (flushTerminalBuffer, destroySession) cancel it unchanged; lastFlushAt is cleaned up in destroySession alongside the write buffer.
This was referenced Jun 12, 2026
Merged
abasiri
pushed a commit
that referenced
this pull request
Aug 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Measurement (2026-06-12, live instance)
While one Claude session streams, the renderer's Compositor thread burns 40-60% of a core — terminal data is batched per-rAF, so every frame with pending output triggers parse + paint at 60 fps.
Change
33 ms minimum interval between flushes (
MIN_FLUSH_INTERVAL_MS), tracked per session inlastFlushAt. When data arrives too soon after a flush, a timer covers the remaining interval before the rAF. The timer reusesbuf.timerIdso the existing teardown (flushTerminalBuffer, destroySession — #55) cancels it with zero new fields;lastFlushAtis cleaned in destroySession.Trade-off
Worst-case +33 ms display latency on streaming text — imperceptible. Keystroke echo is unaffected when idle (first write after ≥33 ms quiet flushes on the next frame as before).
Verification
task checkgreen — 214/214 (4 new tests: throttle window respected, burst coalescing, lastFlushAt cleanup, no late write after destroy). Expected effect: compositor ~50% → ~25% during streams.(Implementation by implementer agent, interrupted by rate-limit mid-run; completed and verified by orchestrator.)