tmux keeps terminal sessions alive after you disconnect. You can start a long-running job over SSH, detach, close the laptop, and reattach later from anywhere. The job is still running and the scrollback is intact.
How tmux is organized¶
tmux uses a client/server model. The first tmux command starts a server process that owns every session. A session holds windows, which work like tabs. A window holds one or more panes, which are splits. Detaching only disconnects the client, so everything inside the session keeps running until the session is killed or the server exits.
Commands are triggered by the prefix key, Ctrl+b by default, followed by a command key. Press the prefix, release it, then press the command key. In the tables below, every key is pressed after the prefix.
Sessions¶
tmux new -s work # start a new named session
tmux new -s work -d # start it detached (useful in scripts)
tmux ls # list sessions with window count and attach state
tmux a -t work # attach ('a' is short for attach-session)
tmux new -A -s work # attach to 'work' if it exists, otherwise create it
tmux rename-session -t old new
tmux kill-session -t work
tmux kill-server # kill every session
| Key | Action |
|---|---|
d |
Detach from the session |
s |
Choose a session interactively |
$ |
Rename the current session |
( / ) |
Switch to the previous or next session |
tmux new -A -s work is a good default in shell aliases and SSH RemoteCommand entries, because it never creates a duplicate session.
Windows¶
| Key | Action |
|---|---|
c |
Create a window |
, |
Rename the current window |
w |
Choose a window interactively |
n / p |
Next or previous window |
0–9 |
Jump to a window by number |
f |
Find a window by searching pane content |
& |
Kill the current window (asks for confirmation) |
Panes¶
| Key | Action |
|---|---|
" |
Split top/bottom (new pane below) |
% |
Split left/right (new pane to the right) |
| Arrow keys | Move focus between panes |
o |
Cycle focus to the next pane |
z |
Zoom the focused pane to full window, press again to restore |
x |
Kill the current pane (asks for confirmation) |
{ / } |
Swap the pane with the previous or next pane |
Ctrl+arrow |
Resize the pane by one cell (repeatable without re-pressing the prefix) |
Alt+arrow |
Resize the pane by five cells |
Space |
Cycle through the built-in layouts |
! |
Break the pane out into its own window |
q |
Show pane numbers |
The CLI equivalents are tmux split-window -v for " and tmux split-window -h for %. tmux names splits by how the panes are stacked rather than by the direction of the dividing line, which is why the flags look backwards to most people.
Copy mode and scrollback¶
Copy mode is how you scroll back through output and copy text.
| Key | Action |
|---|---|
[ |
Enter copy mode (scroll with arrows, PageUp/PageDown, or search) |
] |
Paste the most recent buffer |
= |
Choose from saved paste buffers |
Inside copy mode, the keys depend on mode-keys:
| Action | vi mode | emacs mode (default) |
|---|---|---|
| Start selection | Space |
Ctrl+Space |
| Copy selection and exit | Enter |
Alt+w |
| Search forward / backward | / / ? |
Ctrl+s / Ctrl+r |
| Exit copy mode | q |
q or Escape |
Set setw -g mode-keys vi (see the next section) to get vi navigation.
Configuration¶
tmux reads ~/.tmux.conf, or ~/.config/tmux/tmux.conf on tmux 3.1 and later. These settings are worth having on every machine:
set -g mouse on # click to focus panes, drag borders to resize, wheel to scroll
set -g history-limit 50000 # scrollback lines per pane (default is 2000)
set -g base-index 1 # number windows from 1 to match the keyboard
setw -g pane-base-index 1 # number panes from 1 as well
set -g renumber-windows on # close gaps in window numbers when a window is killed
setw -g mode-keys vi # vi keys in copy mode
set -g status-interval 5 # refresh the status bar every 5 seconds
bind r source-file ~/.tmux.conf \; display "Reloaded"
With mouse on, tmux captures mouse selection. Hold Shift while dragging to select text with your terminal emulator instead.
Changes to the config file don't apply to a running server until you reload it, either with the r binding above or with tmux source-file ~/.tmux.conf.
Scripting a layout¶
Every key binding has a CLI equivalent, so a full working environment can be built from a script:
#!/usr/bin/env bash
session=work
if ! tmux has-session -t "$session" 2>/dev/null; then
tmux new-session -d -s "$session" -n editor
tmux send-keys -t "$session:editor" 'vim' C-m
tmux split-window -h -t "$session:editor"
tmux send-keys -t "$session:editor" 'htop' C-m
tmux new-window -t "$session" -n logs
tmux send-keys -t "$session:logs" 'journalctl -f' C-m
fi
tmux attach -t "$session"
Targets use the form session:window.pane. After a split, the new pane becomes the active one, so targeting just session:window sends keys to it. That avoids hard-coding pane numbers, which change if pane-base-index is set.
The has-session check makes the script safe to run repeatedly: the first run builds the layout and later runs just reattach. For layouts defined in YAML instead of shell, look at tmuxinator or tmuxp.
Nested tmux over SSH¶
If you SSH from inside a local tmux session into a host that also runs tmux, both servers respond to Ctrl+b, and the outer one always gets it first. Two fixes:
- Press the prefix twice.
Ctrl+b Ctrl+bsends a literalCtrl+bthrough to the inner session, soCtrl+b Ctrl+b ddetaches the remote session. - Give the remote tmux a different prefix in its
~/.tmux.conf:
tmux
unbind C-b
set -g prefix C-a
bind C-a send-prefix
Logging pane output¶
pipe-pane sends everything a pane prints to a shell command, which gives you a plain-text transcript without extra tools:
tmux pipe-pane -o 'cat >> ~/logs/pane-$(date +%F).log'
The -o flag makes the command a toggle: it opens the pipe only if none is open, so running the same command again stops logging. Running tmux pipe-pane with no command also stops it. Logging starts from the moment you run the command and does not include existing scrollback.
To save what is already in the scrollback, capture it instead:
tmux capture-pane -p -S - > ~/logs/scrollback.log # -S - starts from the oldest line in history
The log contains raw terminal output, including color and cursor escape codes. Read it with less -R.
Recording sessions¶
pipe-pane produces a transcript, not a recording you can replay. For that, use a dedicated recorder:
| Need | Tool |
|---|---|
| A quick recording with nothing to install | script and scriptreplay (util-linux) |
| A recording to publish or embed on a web page | asciinema |
| A GIF for a README or a site without a JavaScript player | agg (converts asciinema .cast files) or ttyrec with ttygif |
| A continuous plain-text audit trail of one pane | tmux pipe-pane, above |
To share a live session with someone else rather than record it, see tmate, a tmux fork built for pair sessions.
Cheat sheet¶
tmux new -A -s name attach or create a named session
tmux ls list sessions
tmux a -t name attach
Ctrl+b d detach
Ctrl+b c new window
Ctrl+b " / % split top/bottom / left/right
Ctrl+b arrow move between panes
Ctrl+b z zoom pane
Ctrl+b [ copy mode
Ctrl+b ] paste
Ctrl+b Ctrl+b <key> send a key to a nested tmux
tmux pipe-pane -o 'cat >> f.log' toggle logging of pane output
References¶
- tmux on GitHub and its wiki
man tmux: the reference for every command and config option- Related: screen, reptyr (move a running process into a tmux session)