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
| Key | Action | Notes |
|---|---|---|
prefix % | Split side-by-side | | shape: a vertical divider |
prefix " | Split top-and-bottom | Horizontal divider |
prefix ↑↓←→ | Move between panes | Repeatable; hold the arrow |
prefix o | Next pane | Cycles in layout order |
prefix ; | Jump to the last active pane | The edit→run→edit hop |
prefix q | Flash pane numbers; press one to jump | Fastest way across 4+ panes |
prefix z | Zoom the current pane | Same key restores. The focus key |
prefix { / prefix } | Swap pane with previous / next | Rearranges without moving yourself |
prefix x | Kill 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:
| Command | What it does |
|---|---|
join-pane | Move the marked pane into the current pane’s window |
join-pane -h | Same, 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-panefamily (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:
| Key | Layout | Good for |
|---|---|---|
prefix M-1 | even-horizontal | Three panes in a row |
prefix M-2 | even-vertical | Stacked: editor / test / logs |
prefix M-3 | main-horizontal | Big pane on top, output below |
prefix M-4 | main-vertical | Editor left, stack right: the IDE look |
prefix M-5 | tiled | Grid: the dashboard |
prefix E | spread current panes evenly | Untangling 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
| Key | Action |
|---|---|
prefix c | New window |
prefix 0-9 | Jump to window by number |
prefix p / prefix n | Previous / next window |
prefix l | Last window: ping-pong between two |
prefix , | Rename window |
prefix . | Move window to a new index |
prefix w | Window tree, all sessions, searchable |
prefix s | Session tree |
prefix ( / prefix ) | Previous / next session |
prefix d | Detach; 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:
| Key | Job |
|---|---|
prefix % / prefix " | Split |
prefix z | Zoom in / out |
prefix ; | Back to the last pane |
prefix q | Pane numbers, jump |
prefix arrow | Directional pane hop |
prefix Space / prefix M-4 | Cycle / set layout |
prefix c, prefix n, prefix l | Window: new, next, last |
prefix ! | Pane → own window |
prefix m then prefix J | Pull the marked pane here |
prefix d | Detach |
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.