tmux
tmux tutorial for beginners: sessions, windows, panes
A start-to-finish tmux tutorial: the server/session/window/pane model, your first split, detaching and reattaching, and a minimal config that sticks.
tmux is a terminal multiplexer: one program that runs shells and other programs inside persistent sessions that survive your terminal closing. You start a session, split it into panes, detach when you need to walk away, and reattach later to find everything exactly as you left it. This tutorial goes from nothing installed to a working daily setup.
The mental model
Four words explain almost everything that confuses people about tmux: server, session, window, pane.
| Level | What it is |
|---|---|
| Server | One background process per machine, started automatically by your first tmux command |
| Session | A named container of windows โ the thing that survives you disconnecting |
| Window | A tab inside a session, with its own name, shown in the status bar |
| Pane | A split within a window โ one window can hold several panes side by side or stacked |
The relationship is strictly nested: a server runs many sessions, a session holds many windows, a window holds many panes. Nothing above the server level is shared between machines โ a session lives entirely on whichever machine started it, which is why attaching over SSH puts you back in the same place even after your laptop sleeps and reconnects.
If you only take one thing from this section: detaching is not closing. Closing your terminal window while attached to tmux over SSH just drops the connection โ the session, and everything running in it, keeps going on the server.
Install first if you haven't
This tutorial assumes tmux -V already prints something. If it doesn't,
installing tmux covers every major package manager and building from
source.
Your first session
Start tmux
Run tmux new -s intro in a terminal. tmux takes over the screen, draws a status bar at the
bottom (or top, depending on config), and drops you into a shell โ the same shell you'd have
gotten without tmux, just running inside a pane now.
Notice what didn't change
Type a command, run ls, do anything you'd normally do. Nothing about how the shell behaves is
different. tmux doesn't intercept your keystrokes except for one specific chord, covered next.
Learn the prefix key
Every tmux command that isn't typed at a shell prompt starts with the prefix key: Ctrl-b
by default. Press and release it, then press a second key. Ctrl-b d means
"prefix, then d" โ two separate keypresses, not a three-finger chord.
Detach
Press Ctrl-b then d. Your terminal returns to a normal shell prompt, and
prints [detached (from session intro)]. The session is still running โ you just stepped away
from it.
Your first split
Panes are where tmux stops being "a session that survives disconnects" and starts being genuinely useful day to day โ running an editor and a server side by side, in one window, without switching applications.
Reattach
tmux attach -t intro (or the shorthand tmux a if it's your only session) puts you back
exactly where you detached.
Split vertically
Ctrl-b then % splits the current pane into two, side by side. The %
looks like a vertical divider if you squint, which is the entire mnemonic.
Split horizontally
Ctrl-b then " splits the current pane into two, stacked. " looks like
two marks stacked on top of each other.
Move between panes
Ctrl-b then an arrow key moves focus to the pane in that direction. Whatever pane has
focus is the one your keystrokes go to.
Zoom a pane
Ctrl-b then z expands the current pane to fill the whole window without
changing the layout underneath. Press it again to restore. This is the single most useful pane
binding once you have more than two panes open โ zoom in to read a full stack trace, zoom back
out.
Detach and reattach, for real this time
The point of all of the above is a workflow, not a party trick. Start something long-running, detach, come back later โ from the same terminal, a different terminal, or a different machine over SSH โ and reattach:
This is the entire reason tmux exists. A process started in a normal terminal dies when that
terminal closes (technically: it receives SIGHUP). A process started inside tmux keeps
running because it's a child of the tmux server, not of whatever terminal you happened to
attach from. tmux attach session goes deeper on what happens when
you reattach with a differently-sized terminal, which is the next thing people trip on.
A minimal, sensible ~/.tmux.conf
You don't need a 300-line config with plugins to get real value out of tmux. This is enough to fix the handful of defaults that genuinely surprise people:
# Easier-to-reach prefix
set -g prefix C-a
unbind C-b
bind C-a send-prefix
# Start numbering at 1, not 0 โ matches the keyboard row
set -g base-index 1
setw -g pane-base-index 1
# New panes open in the current pane's directory, not $HOME
bind '"' split-window -v -c "#{pane_current_path}"
bind '%' split-window -h -c "#{pane_current_path}"
# Only resize a window for clients actually viewing it
setw -g aggressive-resize on
# Reload config without restarting tmux
bind r source-file ~/.tmux.conf \; display "reloaded"Reload it with tmux source-file ~/.tmux.conf, or just press prefix r once the
binding above is loaded for the first time.
Resist the urge to add everything at once
Every line in a tmux config is something you now have to remember you changed. Add one thing when a specific default annoys you, not ten things because a blog post listed them. The config above is deliberately small.
The five habits that make it stick
Name every session at creation
tmux new -s work, not bare tmux. tmux ls showing work and scratch instead of 0 and
1 is the difference between attaching confidently and guessing. See
tmux new session for the full naming story.
Detach instead of closing
prefix d becomes the default way you end a terminal session, not exit or closing
the window. It costs the same effort and never loses your place.
Name windows, not just sessions
prefix , and typing api takes two seconds and turns a status bar full of zsh zsh zsh into something you can actually navigate by glancing at it.
Learn prefix z before anything fancier
Zoom is worth more than most plugins. You get a full-screen pane on demand without breaking a carefully arranged layout.
Keep prefix ? as your real cheat sheet
It lists every binding your current config actually has โ more accurate than any article,
because it reflects your own ~/.tmux.conf, not a generic default.
Where to go from here
This tutorial covers the mental model and the workflow; tmux commands is the reference table to keep open once the concepts click, grouped by session, window, pane and copy-mode operations rather than explained step by step. If tmux is going to run something long โ a build, a dev server, an agent โ on a machine you're not always sitting at, checking on it means either SSHing back in and reattaching, or, if you'd rather be told the moment it's done instead of remembering to check, running mtmux alongside it to get a push notification.
What is tmux used for?
Running shells and programs inside sessions that keep running after you disconnect. The most common use is starting a long job over SSH, detaching, and reattaching later without losing output or having the job killed.
What is the tmux prefix key?
Ctrl-b by default, pressed and released before the command key โ not held together
with it. Most people remap it to Ctrl-a because it's easier to reach on a standard
keyboard.
How do I exit tmux without killing my session?
Detach with prefix d. Typing exit or pressing Ctrl-d in every pane
closes the window (and eventually the session) instead โ that's the one to avoid if you want to
come back to it.
How do I split panes in tmux?
prefix % splits vertically (side by side), prefix " splits horizontally
(stacked). Move between panes with prefix plus an arrow key.
Do I need a tmux.conf to use tmux?
No โ tmux works fully out of the box. A config file is worth adding once specific defaults start bothering you (the prefix key, window numbering starting at 0), not before.
Put this to work โ mtmux attaches to the tmux server you already run.