ssh into a machine, start a long-running process, lose the connection, lose the process. tmux solves this by decoupling the terminal from the session. the process keeps running whether or not a client is attached.
beyond persistence, tmux provides panes, windows, and sessions - all inside a single terminal. there’s no need to open five tabs or tile terminal windows manually.
core concepts
a session is a collection of windows. a window is a full-screen layout. a pane is a split within a window. sessions persist on the server until explicitly killed, surviving disconnects and terminal closures.
tmux new -s work # create a named session
tmux ls # list sessions
tmux attach -t work # reattach
tmux kill-session -t work # killing a named session
detach from inside a session with ctrl-b d. the session stays alive.
splits and navigation
the default prefix is ctrl-b. after pressing it:
%- vertical split"- horizontal splito- cycle panesz- zoom current panec- new windown/p- next or previous window
zooming a pane with z gives a full-screen view of one pane temporarily without closing the others.
configuration
the defaults are workable but not great. a few changes in ~/.tmux.conf that make a difference:
# start window numbering at 1
set -g base-index 1
setw -g pane-base-index 1
# split with intuitive keys
bind | split-window -h
bind - split-window -v
starting indices at 1 matches keyboard layout - reaching for 0 as the first window is harder than starting from 1.
the tmux configuration used by myself, along with the rest of my terminal setup, is available in my dotfiles/tmux/.tmux.conf.
sessions as workspaces
the real productivity gain comes from using sessions as project workspaces:
tmux new -s infrastructure
tmux new -s monitoring
switch between them with ctrl-b s to get a session picker, or ctrl-b ( and ) to cycle. each session preserves its layout, working directories, and running processes.
when it matters
tmux is most valuable on remote machines. an ssh disconnect during a database migration no longer means an interrupted operation with unknown state. the session keeps running, and reattaching once the connection recovers picks up exactly where it left off. it’s also useful on the desktop as a way to switch between different running processes.
what to watch out for
the prefix key collides with shell and editor bindings. ctrl-b is the default, but it overlaps with readline’s “move back one character” and with paging in some tools. remapping it to ctrl-a or ctrl-space is common, though ctrl-a then clashes with readline’s “start of line” and needs a double-tap binding to pass through.
a killed session takes its processes with it. tmux persistence survives disconnects, not reboots or kill-session. once the session is gone, every process inside it is gone too. for state that must outlive the session, use a service manager, not a tmux window.
scrollback works differently than a normal terminal. the mouse wheel doesn’t scroll by default - scrolling happens in copy mode (ctrl-b [), and the native terminal scrollbar only sees the current pane’s output. enabling set -g mouse on restores wheel scrolling at the cost of changing selection behaviour.
nested tmux sessions swallow the prefix. running tmux inside an ssh session that is itself inside tmux means the outer session intercepts the prefix. send a command to the inner session by pressing the prefix twice (ctrl-b ctrl-b).
references
[1] tmux github repository. “terminal multiplexer.”
github.com/tmux/tmux
[2] tmux manual. “tmux(1).“
man.openbsd.org/tmux
[3] levi van noort. “dotfiles - tmux configuration.”
github.com/levivannoort/dotfiles/blob/main/tmux/.tmux.conf