Terminal multiplexer — from zero to competent
The server persists in the background. Detach from a session, close your terminal, reconnect later — everything is still running.
# All tmux keybindings start with a prefix (default: Ctrl-b).
# It's a SEQUENCE, not a chord: press Ctrl-b, release, then press the command key.
# This cheatsheet uses C-b to mean the prefix throughout.
C-b = Ctrl + b → release → <command key>
tmux # Start new unnamed session.
tmux new -s work # Start session named "work".
tmux new -s work -n editor # …with first window named "editor".
tmux ls # List all sessions. Also: tmux list-sessions.
tmux a # Attach to last session. Also: tmux attach.
tmux a -t work # Attach to session named "work".
tmux kill-session -t work # Kill session named "work".
tmux kill-server # Kill everything — all sessions, the server itself.
| Keys | Action |
|---|---|
| C-b d | Detach from session (session keeps running) |
| C-b s | Interactive session/window picker (tree view, arrows + enter) |
| C-b $ | Rename current session |
| C-b ( | Switch to previous session |
| C-b ) | Switch to next session |
| C-b L | Switch to last (most recently used) session |
tmux new -s proj → work → C-b d → disconnect → reconnect → tmux a -t proj → everything is still there.Windows are tabs. The status bar at the bottom shows them; * marks the active one.
| Keys | Action |
|---|---|
| C-b c | Create new window |
| C-b , | Rename current window |
| C-b n | Next window |
| C-b p | Previous window |
| C-b 0-9 | Jump to window by number |
| C-b w | Interactive window picker (tree of all sessions & windows) |
| C-b & | Kill current window (with confirmation prompt) |
| C-b l | Toggle to last active window |
| C-b f | Find window by name |
# Reorder windows from command mode (C-b :)
swap-window -s 2 -t 0 # Move window 2 to position 0.
move-window -t 5 # Move current window to position 5.
| Keys | Action |
|---|---|
| C-b % | Split vertically (left | right) |
| C-b " | Split horizontally (top / bottom) |
| C-b ←↑↓→ | Move focus between panes |
| C-b q | Flash pane numbers (type a number to jump) |
| C-b o | Cycle to next pane |
| C-b ; | Toggle to last active pane |
| Keys | Action |
|---|---|
| C-b z | Zoom pane to full screen (toggle — press again to restore) |
| C-b Space | Cycle through pane layouts (even-h, even-v, main-h, main-v, tiled) |
| C-b { | Swap current pane with previous |
| C-b } | Swap current pane with next |
| C-b C-←↑↓→ | Resize pane in direction (hold Ctrl + arrow after prefix) |
| C-b x | Kill current pane (with confirmation) |
| C-b ! | Break pane out into its own window |
# Precise resize from command mode (C-b :)
resize-pane -D 10 # Grow down by 10 rows. -U / -L / -R for other dirs.
resize-pane -t 2 -x 80 # Set pane 2 width to 80 columns.
resize-pane -t 2 -y 50% # Set pane 2 height to 50% of window.
tmux has its own scrollback buffer. You must enter copy mode to scroll, search, or select text.
| Keys | Action |
|---|---|
| C-b [ | Enter copy mode |
| q | Exit copy mode |
| ↑ ↓ PgUp PgDn | Scroll (arrow keys or page keys) |
| g / G | Jump to top / bottom of buffer (vi mode) |
| / or ? | Search forward / backward (vi mode) |
| n / N | Next / previous search match |
Space # Start selection.
Enter # Copy selection to tmux buffer and exit copy mode.
C-b ] # Paste from tmux buffer.
v # Toggle between character / line selection (if vi-mode).
# Add to ~/.tmux.conf to pipe copied text to system clipboard:
# macOS
bind -T copy-mode-vi y send -X copy-pipe-and-cancel "pbcopy"
# Linux (X11)
bind -T copy-mode-vi y send -X copy-pipe-and-cancel "xclip -sel clipboard"
# Linux (Wayland)
bind -T copy-mode-vi y send -X copy-pipe-and-cancel "wl-copy"
C-b : # Open command prompt at bottom of screen.
# Tab completion works. Any tmux command is valid.
list-keys # Show all keybindings. Also: C-b ?
list-commands # Show all available commands.
show-options -g # Show global options.
display-message "#S:#I.#P" # Display current session:window.pane.
set -g mouse on # Enable mouse support live. "off" to disable.
setw synchronize-panes on # Type in all panes simultaneously. Great for multi-
# server commands. "off" to disable.
capture-pane -pS -1000 | \
save-buffer /tmp/tmux.log # Dump 1000 lines of scrollback to a file.
Config lives at ~/.tmux.conf. Reload with: tmux source-file ~/.tmux.conf or from inside: C-b : → source-file ~/.tmux.conf
# ── Prefix ──────────────────────────────────────────────
unbind C-b
set -g prefix C-a # C-a is closer to home row (also screen compat).
bind C-a send-prefix # Press C-a C-a to send literal C-a.
# ── Sane Splits ─────────────────────────────────────────
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"
# ── Navigation ──────────────────────────────────────────
bind h select-pane -L # vim-style pane movement.
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# ── Mouse ───────────────────────────────────────────────
set -g mouse on # Click panes, resize with drag, scroll.
# ── Windows ─────────────────────────────────────────────
set -g base-index 1 # Start numbering at 1 (0 is far away).
setw -g pane-base-index 1
set -g renumber-windows on # Close window 2 → window 3 becomes 2.
# ── Performance ─────────────────────────────────────────
set -sg escape-time 0 # No delay after pressing Escape (vital for vim).
set -g history-limit 50000 # Generous scrollback buffer.
set -g display-time 3000 # Messages stay visible 3 seconds.
# ── Copy Mode ───────────────────────────────────────────
setw -g mode-keys vi # vi keybindings in copy mode.
# ── Status Bar ──────────────────────────────────────────
set -g status-style "bg=default,fg=white"
set -g status-left "#[bold]#S "
set -g status-right "%H:%M"
# ── True Color ──────────────────────────────────────────
set -g default-terminal "tmux-256color"
set -ag terminal-overrides ",xterm-256color:RGB"
#S session name #I window index #W window name
#P pane index #T pane title #H hostname
#F window flags #D pane id #{pane_current_path}
# Send a command to a running session without attaching.
tmux send-keys -t work "make test" Enter
# Target a specific window and pane.
tmux send-keys -t work:2.1 "tail -f /var/log/app.log" Enter
# Target format: session:window.pane
# work:2.1 → session "work", window 2, pane 1
#!/bin/bash
# Create a dev layout: editor + server + logs
tmux new-session -d -s dev -n editor
tmux send-keys -t dev:editor "vim ." Enter
tmux new-window -t dev -n server
tmux send-keys -t dev:server "npm run dev" Enter
tmux new-window -t dev -n logs
tmux split-window -t dev:logs -h
tmux send-keys -t dev:logs.0 "tail -f /var/log/app.log" Enter
tmux send-keys -t dev:logs.1 "tail -f /var/log/error.log" Enter
tmux select-window -t dev:editor
tmux attach -t dev
# Run a command whenever a new session is created.
set-hook -g after-new-session "run-shell 'notify-send tmux Session\\ started'"
# Auto-rename window based on running process.
setw -g automatic-rename on
# One session per project. Switch between them instantly.
tmux new -s frontend # React app, test runner, git
tmux new -s backend # API server, DB console, logs
tmux new -s infra # Terraform, monitoring, SSH tunnels
C-b s # Session picker — jump between projects in 1 second.
# Two people attach to the same session — both see and type the same thing.
# Person A:
tmux new -s pair
# Person B (same machine or via ssh):
tmux a -t pair
# Window 1 "code": main editor (vim/nvim), zoomed most of the time
# Window 2 "run": split — test runner on top, git on bottom
# Window 3 "db": database REPL
#
# Use C-b z to zoom/unzoom the editor pane as needed.
# Use C-b 1 / C-b 2 / C-b 3 to jump between concerns.
# Type in all panes at once — great for multi-server admin.
C-b : → setw synchronize-panes on
# Now every keystroke goes to all panes in the window.
C-b : → setw synchronize-panes off # Turn it off when done.
# "sessions should be nested with care, unset $TMUX to force"
# → You're in tmux and trying to start tmux. Use C-b c for a new window instead.
# → Or detach first (C-b d), then attach to the other session.
# Escape key is slow (vim users)
# → Add to config: set -sg escape-time 0
# Colors look wrong
# → set -g default-terminal "tmux-256color"
# → set -ag terminal-overrides ",xterm-256color:RGB"
# Mouse scroll shows history instead of scrollback
# → set -g mouse on
# "no sessions" after reboot
# → tmux doesn't survive reboots natively.
# → Use tmux-resurrect plugin or recreate with a bootstrap script.
# Nested tmux (local → ssh → remote tmux)
# → C-b C-b sends prefix to inner tmux.
# → Or set a different prefix on the remote machine.
The 20 commands you'll use every day. Master these and you're competent.
| Category | Keys | Action |
|---|---|---|
| Sessions | tmux new -s <name> | Create named session |
| tmux a -t <name> | Attach to session | |
| C-b d | Detach | |
| Navigate | C-b s | Session picker |
| C-b w | Window/session tree | |
| C-b 0-9 | Jump to window N | |
| C-b ←↑↓→ | Switch pane | |
| Windows | C-b c | New window |
| C-b , | Rename window | |
| C-b n / p | Next / previous window | |
| C-b & | Kill window | |
| Panes | C-b % | Split left|right |
| C-b " | Split top/bottom | |
| C-b z | Zoom / unzoom pane | |
| C-b x | Kill pane | |
| C-b Space | Cycle layouts | |
| Copy | C-b [ | Enter copy/scroll mode |
| q | Exit copy mode | |
| / then n/N | Search in scrollback | |
| Meta | C-b ? | List all keybindings |
# Plugin manager: github.com/tmux-plugins/tpm
# Install: git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
# Then add to ~/.tmux.conf:
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible' # Sane defaults everyone agrees on.
set -g @plugin 'tmux-plugins/tmux-resurrect' # Save/restore sessions across reboots.
set -g @plugin 'tmux-plugins/tmux-continuum' # Auto-save sessions every 15 minutes.
set -g @plugin 'tmux-plugins/tmux-yank' # System clipboard integration.
run '~/.tmux/plugins/tpm/tpm' # Must be last line. C-b I to install plugins.