Handling nested tmux when SSHing into servers that also run tmux via send-prefix and prefix remapping, then optimizing terminal input: mouse, extended keys, focus events, OSC 52 clipboard, and true color end-to-end.

In episode 20 we covered security & hardening — locking sessions, securing the socket, and hiding secrets from the config. That security foundation is now the stepping stone to something more subtle: how you interact with tmux in the most complex yet most common real-world scenarios. Two big themes await: nested tmux when you SSH into servers that also run tmux, and advanced input handling to make the terminal feel as fast and sharp as possible.
Why does this matter? An engineer working in real infrastructure will almost certainly face tmux on two layers at once: on the laptop and on the production server. If both layers fight over the same prefix, you can't control anything calmly. And on the input side, a few milliseconds' difference on ESC or a wrong color choice isn't just comfort — it decides whether you can work fast or end up stopping because the text is unreadable. This episode refers to tmux 3.7b as the latest stable version.
From episode 18 we know the remote work pattern: open tmux on the laptop, SSH into a server, and often there's tmux inside again — started by a previous admin, by a deploy tool, or by team habit. The result: two layers both claiming the C-b prefix. Every C-b you press gets swallowed by the outer layer, and the tmux inside the server seems "unreachable".
The key concept is layered prefixes. Each layer has its own prefix; your only job is sending the prefix to the right layer. Imagine two stacked doors: the outer door key and the inner door key may be the same, as long as you know which key goes to which door — and here the key is the order of keystrokes.
tmux's default actually already has this mechanism: C-b twice sends the prefix to the application inside the pane. The built-in C-b binding in the prefix table is send-prefix — pressing C-b inside prefix mode forwards a literal C-b to the program in the pane, i.e. to the inner-layer tmux. Let's make this more comfortable with an explicit binding:
set -g prefix C-b
bind C-a send-prefixWith this line, C-b then C-a will send a C-b to the pane — and since that pane is tmux on the server also using C-b, the server "hears" its prefix. The complete map:
| Situation | Combination |
|---|---|
| Outer-layer tmux command (local) | C-b then command, e.g. c |
| Send prefix to the inner-layer tmux | C-b then C-a |
| Inner-layer tmux command (e.g. new window) | C-b C-a then c |
| Detach from the inner-layer tmux | C-b C-a then d |
Send a literal C-b to the application inside | C-b C-a then C-b |
Note the last line: after sending the prefix to the inner layer, we use that inner layer's own default binding (C-b C-b) to forward the prefix even deeper. This pattern is recursive — as long as each layer uses C-b plus send-prefix, you can penetrate any number of layers.
A popular alternative is giving each layer its own "language" so there's no ambiguity. The approach many teams use: the local layer uses C-b, and the server layer is explicitly set to C-b too — but with bind C-a send-prefix on the local side, the transition feels like one light extra keystroke. The most important thing: write the prefix explicitly on both sides, don't rely on the implicit default.
set -g prefix C-b
bind C-a send-prefixMarking the inner layer with a different status bar (status-left "REMOTE ") is a small trick that helps a lot: in an instant you know which layer you're on, so you don't press the wrong detach combination. Clear conventions on the status bar prevent expensive mistakes — like detaching from the wrong layer.
Tip
If you prefer C-a as the main prefix, apply the same config on both layers: set -g prefix C-a, unbind C-b, and bind C-a send-prefix on both local and remote. As long as both layers use the identical prefix, C-a C-a will always send the prefix to the next layer. Cross-machine consistency is the key.
set -g mouse onmouse on makes tmux recognize clicks: selecting panes, resizing borders, scrollback with the wheel, even clicking windows in the status bar. It feels like magic for users coming from a GUI. However, there's a trade-off: applications using the mouse inside the terminal (e.g. TUIs that support dragging) lose their events because tmux swallows them. For that kind of workload, turn it off temporarily with set -g mouse off or a toggle binding.
set -g xterm-keys on
set -g extended-keys alwaysxterm-keys on makes tmux translate special keys (Home, End, PageUp, PageDown, Ctrl+Arrow) into correct sequences so applications inside the pane can distinguish them. Since tmux 3.2, xterm-keys is on by default; extended-keys always adds full CSI-u support used by modern editors like Neovim and Emacs for unambiguous key combinations. The effect is most noticeable in editors: Ctrl+Arrow to move by word, Ctrl+Home to go to the start of the document, and so on — instead of printing weird characters.
set -g focus-events onWith focus-events on, tmux tells applications in a pane when the pane gains or loses focus — using bracketed focus events. This matters for editors and tools that react to focus: Neovim can auto-save on losing focus, LSP can discard cache on return, and runners like live-server can stop blazing while the pane isn't visible. The result: a resource-efficient, non-intrusive system.
set -sg escape-time 10escape-time is how long tmux waits after receiving ESC to decide whether it's a lone ESC key or the start of an escape sequence (e.g. Alt+key or arrow keys). The old default of 500 milliseconds makes editors using ESC feel "rubbery" — every exit from insert mode in vim waits half a second. Lowering it to 10 makes ESC feel instant. Since tmux 3.5 the default is indeed 10, but writing it explicitly keeps consistency across machines — while also closing the interpretation window we discussed in episode 20.
set -g set-clipboard onThe classic problem: copy in tmux copy mode, then paste outside the terminal — impossible, because the pane clipboard and the system clipboard are two worlds. set-clipboard on bridges them via OSC 52, a protocol that tells the terminal emulator to store text into the system clipboard. The condition is that your terminal emulator supports it — iTerm2, kitty, foot, WezTerm, and Windows Terminal all do. When it works, you no longer need xclip/xsel or extra plugins: a selection in tmux lands directly on the system clipboard.
Warning
OSC 52 is a two-way bridge worth being aware of: anything on the terminal clipboard is also visible to processes in the pane if they request the clipboard (e.g. via yank in Neovim). On a shared machine, consider whether that's what you want — in strict multi-user environments, disable set-clipboard and keep the pane clipboard separate.
Color in the terminal runs through a chain: application → tmux → terminal emulator. Every link must agree on color capability. If any one of them declares a TERM that's too low, 256-color or true color gets reduced — the editor theme turns dull, and code syntax that should be colored becomes unreadable.
set -g default-terminal "tmux-256color"
set -g terminal-features 'xterm*:RGB'default-terminal sets the TERM applications see inside the pane — tmux-256color tells applications that 256 colors are available. terminal-features 'xterm*:RGB' tells tmux that terminals using the xterm* TERM support true color (RGB), so tmux forwards full 24-bit colors. Verify by comparing echo $TERM inside and outside tmux, then run a color test (e.g. tput colors should print 256).
set -g mouse on
set -g xterm-keys on
set -g focus-events on
set -sg escape-time 10C-b c inside nested tmux creates a new window on the outer layer instead. Send the prefix first (C-b C-a), then the command.status-left "REMOTE ", you easily forget which layer you're on — and detach from the wrong one. Give each layer a visual identity.mouse on without realizing the trade-off. TUIs that depend on the mouse lose their events. Provide a toggle (bind m set -g mouse for example) and know when to turn it off.escape-time. On old tmux or configs copied from old machines, ESC in vim feels rubbery. Set escape-time 10 explicitly.TERM inconsistent inside and out. Applications see wrong colors because default-terminal isn't set to tmux-256color, or RGB features aren't advertised. Compare echo $TERM on both sides.set-clipboard on only means tmux sends the signal; if the terminal emulator doesn't support OSC 52, the clipboard still doesn't stick. Make sure your terminal supports it before removing xclip.This episode completed two big interaction layers with tmux. In nested tmux, you learned to send prefixes between layers with send-prefix, map key combinations for each layer, and mark the inner layer via the status bar. In advanced input, you optimized mouse, extended keys, focus events, and escape-time so the terminal feels sharp — then closed the clipboard and color chain with OSC 52 and true color end-to-end.
Key points to take away:
C-b C-a sends the prefix to the inner layer; this pattern is recursive.escape-time 10 removes ESC lag and closes an interpretation gap.In episode 22 we'll cover popups, menus, and the latest stable features — display-popup for floating terminals, display-menu for custom menus, floating panes and pane scrollbars from tmux 3.6/3.7, plus a case study building a development menu with popups and git keybindings. See you in episode 22!