tmux has ~200 default keybindings, and memorizing them is the wrong goal. The set that pays rent daily is maybe fifteen keys, plus three commands tmux deliberately left unbound that solve the problems the bound keys can’t. This post is that set, not the man page.

The mental model first, because everything below hangs off it: one tmux server hosts many sessions; each session has windows (the tabs in the status bar); each window has one or more panes (the rectangles on screen). Panes are cheap and disposable; windows are where work lives. Most beginners over-use panes and under-use windows; the reverse ages much better.

One housekeeping note: everything here is checked against upstream tmux 3.4 with an empty config (tmux -f /dev/null), and every command was tested live. If your ~/.tmux.conf (or a plugin) rebinds things, tmux list-keys is ground truth on your machine.


Splits, and getting around once you’ve made them

KeyActionNotes
prefix %Split side-by-side| shape: a vertical divider
prefix "Split top-and-bottomHorizontal divider
prefix ↑↓←→Move between panesRepeatable; hold the arrow
prefix oNext paneCycles in layout order
prefix ;Jump to the last active paneThe edit→run→edit hop
prefix qFlash pane numbers; press one to jumpFastest way across 4+ panes
prefix zZoom the current paneSame key restores. The focus key
prefix { / prefix }Swap pane with previous / nextRearranges without moving yourself
prefix xKill pane (with confirmation)
prefix &Kill window (with confirmation)

The one trip-up everybody hits: % and " are named after the divider, not the result. % is a vertical bar → panes sit side by side. " is a double-quote → two lines stacked. Say it out loud once and it sticks.

Two of these deserve promotion into muscle memory ahead of everything else. prefix z is the single best quality-of-life key in tmux: one press gives the current pane the whole window (long build output, a big diff), one press gives your layout back. prefix ; is the heartbeat of the editor-plus-shell workflow: run tests in the bottom pane, watch them fail, press ; and you’re back on the line of code that caused it: no arrow-key counting, no q-lookup.


The four movers tmux never bound

Default tmux can create panes and destroy panes, but it ships almost nothing for moving them around: join-pane, move-pane, and friends have no default bindings. They’re the difference between a tidy workspace and one where you close and re-split everything because a pane landed in the wrong window.

The trick that makes them pleasant is marking. prefix m toggles a mark on the current pane (the mark is global; it survives window switches), and prefix M clears it. Once a pane is marked, the move commands resolve to it automatically:

CommandWhat it does
join-paneMove the marked pane into the current pane’s window
join-pane -hSame, forcing the new pane side-by-side
move-pane -h -s {marked}Same idea, explicit: pull the marked pane next to the current one, even across windows
break-pane (prefix !)Eject the current pane into its own new window
move-window (prefix .)Re-index the current window: type a number, it moves
swap-pane -U/-D ({ / })Trade the current pane with its neighbors

Gotcha worth knowing before it costs you ten minutes: in the swap-pane family (swap-pane, join-pane, move-pane), the marked pane is the implicit source. move-pane -t {marked} (which looks like a sensible “send my pane to the marked one” binding) silently does nothing once a mark exists, because source and target resolve to the same pane. The explicit -s {marked} form above is the one that works.

The daily rhythm this enables:

Eject and re-admit the long-running process. Your dev server doesn’t belong in the editor window, but you started it there. Press prefix ! and it’s now its own window with a status-bar tab you can check with prefix l (last-window). Want it back side-by-side later? Visit its window, prefix m to mark it, go home, prefix J… except J isn’t bound by default. Which brings us to:


A fifteen-line config that pays for itself

# splits that inherit the current directory (defaults don't)
bind - split-window -v -c "#{pane_current_path}"
bind \ split-window -h -c "#{pane_current_path}"

# pull the marked pane into the window you're standing in
bind J join-pane
# ...side-by-side, when you care where it lands
bind S move-pane -h -s {marked}

# repeatable resizes without arrow-key origami
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

set -g mouse on

The -c "#{pane_current_path}" flag is small and outsized: every new pane opens in the directory you were already in, not ~. The resize bindings exist because the defaults are prefix C-arrow (one cell) and prefix M-arrow (five cells, both repeatable); fine, but H/J/K/L is faster to reach and the -r flag makes each press repeat until you move on.

One caution if you copy a popular vim-style pane-navigation config (binding h/j/k/l to direction keys): prefix l is last-window upstream, and those configs shadow it with “move right”. If you live in prefix l, rebind it explicitly (bind L last-window or similar); silently losing it is confusing for exactly as long as it takes you to forget the config change.


Layouts: cycle, or jump straight to the one you want

prefix Space cycles through tmux’s five built-in layouts: even-horizontal, even-vertical, main-horizontal, main-vertical, tiled. Cycling is fine for two panes; for more, jump directly:

KeyLayoutGood for
prefix M-1even-horizontalThree panes in a row
prefix M-2even-verticalStacked: editor / test / logs
prefix M-3main-horizontalBig pane on top, output below
prefix M-4main-verticalEditor left, stack right: the IDE look
prefix M-5tiledGrid: the dashboard
prefix Espread current panes evenlyUntangling a hand-resized mess

(M- is Alt: prefix then Alt-4.) Don’t curate layouts by hand: resize when you need to (-r bindings above, or drag the border with the mouse), and let Space/M-4 do the rest. prefix C-o rotates panes through the layout if you want the same geometry with different contents.


Windows and sessions: the part beginners skip

KeyAction
prefix cNew window
prefix 0-9Jump to window by number
prefix p / prefix nPrevious / next window
prefix lLast window: ping-pong between two
prefix ,Rename window
prefix .Move window to a new index
prefix wWindow tree, all sessions, searchable
prefix sSession tree
prefix ( / prefix )Previous / next session
prefix dDetach; everything keeps running

Two habits turn this table from “aware” to “load-bearing”:

Name your windows, or lose the numbers. The status bar auto-renames windows to the running command, which means window 3 is called vim until you run make in it. prefix , and a two-letter name (ed, srv, log) makes prefix 3 land where you expect every time. Rename also stops the auto-rename, which is what you want.

The window is the unit of context, the pane is the unit of convenience. One window per task: editor panes here, the service stack there, the REPL in its own place. Inside a window, panes are free: split, zoom, throw them away. When a pane starts feeling important, that’s prefix ! asking to be a window.


The daily dozen

If you keep only twelve keys, keep these:

KeyJob
prefix % / prefix "Split
prefix zZoom in / out
prefix ;Back to the last pane
prefix qPane numbers, jump
prefix arrowDirectional pane hop
prefix Space / prefix M-4Cycle / set layout
prefix c, prefix n, prefix lWindow: new, next, last
prefix !Pane → own window
prefix m then prefix JPull the marked pane here
prefix dDetach

Everything else is discoverable when you need it: prefix ? lists all bindings, prefix w shows every window in every session, and the three movers (join-pane, move-pane, break-pane) cover the rearranging that no default key does.

The natural next layer is copy mode: how to yank text out of a pane (and why vi-mode + a good copy-command matters more than any pane trick on this page). That’s a post of its own.