Terminal scrollback not working in long sessions (alternate screen buffer)
Description
Unable to scroll back through conversation history in long CLI sessions. The terminal viewport only retains a limited portion of the session output, making it impossible to review earlier parts of the conversation by scrolling up.
Environment
- OS: macOS (Darwin 25.3.0, Apple Silicon M3)
- Terminal: Terminal.app
- Claude Code versions tested: 2.1.87, 2.1.88, 2.1.89 (same behavior on all three)
- Shell: bash
What I've tried (none of these helped)
- Terminal.app scrollback set to "Limit to available memory" (effectively unlimited)
- Freed up system memory (plenty available)
- Set
CLAUDE_CODE_NO_FLICKER=1environment variable - Tested on versions 2.1.87, 2.1.88, and 2.1.89 (identical behavior)
- Rolled back versions via symlink
Reproduction
- Start a long CLI session with significant output (e.g., multiple browser automation tool calls, reading large files, filling web forms)
- After ~30-60 minutes of active use, try scrolling up to the beginning of the session
- Scrollback stops well short of the beginning; earlier conversation turns are inaccessible
Expected behavior
Full session output should be scrollable in the terminal, as it was in earlier versions of Claude Code.
Likely cause
Claude Code uses the alternate screen buffer, which bypasses the terminal emulator's normal scrollback buffer. The alternate screen's internal viewport appears to have a limited size that doesn't scale with session length.
Impact
This makes it impossible to review earlier parts of a session, which is important when resuming work after a break or verifying what actions were taken. The conversation context is preserved internally (Claude can still reference earlier turns), but the user cannot visually review them.
4 Comments
Yes, I noticed the same thing. And it almost happens - it happens so fast. I was reading something and I scroll down and then I can't scroll back up to re-verify what I just read. It's ridiculous.
Adding some measurements from inside tmux, because they suggest the alternate screen is only half the cause and a fix that only addresses it won't be enough.
Environment: Claude Code v2.1.220, tmux 3.2a, Linux aarch64,
history-limit 50000.1. The pane holds zero lines. With a normal session running, tmux reports:
history_sizestays at 0 for the entire session regardless of length, so there is nothing above or below the viewport to scroll to or select. A mouse drag dies at the pane edge for the same reason.2. Disabling the alternate screen is not sufficient. tmux's
alternate-screen offmakes tmux ignore the?1049h/?1049lsequences entirely, which is equivalent to removing them. With that set I asked Claude to print 200 numbered lines in a 30-row window:History stayed at 4 lines. The renderer repaints its viewport in place rather than emitting lines that scroll, so even with the alternate screen out of the picture the terminal never receives the earlier output.
3. For contrast,
--ax-screen-readerdoes work. Same test, same window size:Scrollback accumulates normally there, and mouse selection, wheel scrolling and drag auto-scroll all behave like any ordinary pane. So the flat-text renderer already emits scrollable output; the default one doesn't.
Why this matters for the fix: the issue body attributes the problem to the alternate screen buffer, but (2) shows dropping the alternate screen alone changes nothing. What's needed is for completed turns to be written as ordinary output the terminal keeps, the way
--ax-screen-readeralready does, rather than being repainted into a fixed viewport.Practical impact: selecting text with the mouse is capped at exactly one screenful, and there is no workaround from the terminal side because the text never reaches the terminal at all.
Environment: Linux (Debian), tmux 3.x, Chrome Remote Desktop
Reproduces the same way in tmux with copy mode. The specific symptom there: entering copy mode and scrolling up shows the shell history from before Claude Code was launched rather than the conversation — because the session content is written to the alternate screen buffer and never reaches tmux's main scrollback (history-limit 50000, confirmed via
history_size). From tmux's perspective the conversation simply doesn't exist in the buffer.This confirms the alternate screen diagnosis in the issue description. It also means tmux-side workarounds (increasing history-limit, plugins, etc.) can't help — the content is never written there to begin with.
Fix found (for existing users with
"tui": "fullscreen"in settings)Checking
~/.claude/settings.jsonrevealed the root cause for users who had scrollback working previously and then lost it:The schema description confirms this is the alt-screen renderer:
Fix: change
tuito"default"in~/.claude/settings.json. Scrollback works immediately in the next session. Tradeoff: some screen flicker during redraws returns.Why it used to work: the
"fullscreen"renderer apparently had working virtualized in-app scrollback at some point, which has since regressed (or never worked correctly inside tmux). Users who had explicitly set"fullscreen"got stuck on the broken mode while new users on"default"may not have noticed.This also explains why
CLAUDE_CODE_NO_FLICKER=1(the env-var equivalent of"fullscreen") didn't help the original reporter — they were testing the broken renderer. The--ax-screen-readerworkaround worked because it forced the"default"renderer, but that flag has since been removed from the CLI.