Fixing SSH Sessions That Don't Know the Terminal's Actual Size
TUI apps render clipped over SSH, or the terminal doesn't rewrap after resizing — the remote shell has a stale idea of the terminal's actual dimensions.
A remote shell over SSH rendering full-screen applications incorrectly, or not adjusting to a resized terminal window, comes down to the remote side having a stale or incorrect idea of your terminal’s actual row and column dimensions.
Step 1: check what the remote shell currently believes about terminal size
stty size
echo "COLUMNS=$COLUMNS LINES=$LINES"
Compare this against your terminal emulator’s actual current window size — a clear mismatch confirms the diagnosis directly.
Step 2: understand how terminal size normally gets communicated
Terminal dimensions are normally communicated to the remote shell automatically, via a SIGWINCH signal sent whenever the local terminal window is resized — the remote shell (and any TUI application it’s running) is supposed to receive this signal and query the new dimensions in response.
Step 3: force a manual resize signal if automatic sync isn’t happening
kill -WINCH $$
Manually sending SIGWINCH to the current shell process forces it to re-query terminal dimensions immediately — a useful direct fix when the automatic resize notification didn’t reach the shell for some reason.
Step 4: check for a stuck tmux or screen session specifically
tmux attach
# if reattaching to a running session on a different-sized
# terminal, resize is usually automatic — but check the
# tmux status bar's reported size against your actual window
Terminal multiplexers add another layer that tracks its own idea of terminal size independently — detaching from a multiplexer session on one differently-sized terminal and reattaching from another can occasionally leave a stale size cached until the multiplexer itself is prompted to recheck.
Step 5: check your SSH client’s pty allocation settings
ssh -tt user@host
Forcing pseudo-terminal allocation explicitly (-tt) ensures the remote side actually has a proper pty to report size through — some specific SSH invocations (particularly ones running a single remote command rather than an interactive session) may not allocate a pty by default at all.
Step 6: check whether the specific TUI application itself handles resize correctly
# most well-behaved ncurses/TUI applications refresh their
# layout automatically on SIGWINCH — a few older or poorly
# maintained ones don't
If the shell itself correctly reports the right size (confirmed via stty size) but one specific application still renders incorrectly after a resize, the bug may be in that specific application’s own resize handling rather than anywhere in the shell or SSH layer.
Step 7: verify the fix by resizing your terminal window and checking again
stty size
Resizing your local terminal window, then immediately re-checking stty size on the remote side, confirms whether size synchronization is now working correctly going forward, not just whether the current mismatch happened to get corrected once.
Step 8: for a persistent, recurring problem, check your terminal emulator’s own SIGWINCH behavior
A terminal emulator that doesn’t properly send SIGWINCH to the process it’s connected to on every resize (unusual, but possible with some unusual or misconfigured terminal setups) would cause this problem to recur consistently across every SSH session — worth testing with a different terminal emulator if the problem persists across otherwise-unrelated remote hosts.
Why this is fundamentally a signal-delivery problem, not an SSH-specific bug
Terminal size synchronization depends on SIGWINCH actually being generated and delivered correctly through however many layers sit between your physical terminal window and the remote shell process — SSH, tmux, and any TUI application in between all need to participate correctly in this chain, which is why the fix sometimes lives at a different layer than where the symptom first appears.
The actual kernel-level mechanism underneath SIGWINCH
SIGWINCH and terminal dimensions aren’t the same thing — the signal is just a notification that something changed; the actual current row and column counts live in kernel state associated with the pty, queried via the TIOCGWINSZ ioctl call on the terminal’s file descriptor. The typical flow is: something (an SSH client, a terminal emulator, tmux) calls TIOCSWINSZ to update that kernel-held size, which automatically triggers SIGWINCH delivery to the foreground process group attached to that terminal; a well-behaved application’s signal handler then calls TIOCGWINSZ to actually read the new dimensions back out. Manually sending SIGWINCH without anything having actually updated the underlying kernel state first accomplishes nothing — it only helps when the real size already changed and the notification itself simply didn’t arrive.
A simpler, older command that does the same underlying job
resize
Predating the more manual stty size/kill -WINCH approach above, the resize utility (commonly bundled with xterm) prints and exports correctly-detected COLUMNS and LINES shell variables by having the terminal itself report its own dimensions via a query escape sequence, then evaluating the response — a self-contained one-command fix worth trying first on a system that has it installed, before working through the more manual signal-and-ioctl diagnostic steps above.
Related:
Sources: