What Is tmux and Why Use It?
Tmux (terminal multiplexer) solves three common developer problems:
- Persistent sessions — Start a long-running process (tests, build, server), detach from the terminal, and reattach later — even after closing your SSH connection.
- Multiple terminals in one window — Split your terminal into panes to see your editor, server logs, and tests side by side.
- Session management — Name and organise your work into separate sessions (one per project), and switch between them instantly.
Mental Model: Sessions > Windows > Panes
tmux
└── Session: "work"
├── Window 1: "editor" ← active window
│ ├── Pane 1: vim src/app.ts
│ └── Pane 2: npm run dev
└── Window 2: "logs"
└── Pane 1: tail -f server.log
└── Session: "personal"
└── Window 1: "dotfiles"
└── Pane 1: bash
- Session — A persistent workspace. Detaching from a session doesn’t kill it.
- Window — Like a tab in a browser. Each window fills the full terminal.
- Pane — A split within a window. Multiple panes share a window’s space.
Getting Started
# Install tmux
# macOS:
brew install tmux
# Ubuntu/Debian:
sudo apt install tmux
# Start a new tmux session
tmux
# You'll see a status bar at the bottom — you're now inside tmux
The Prefix Key: Every tmux command starts by pressing a prefix key combination, then a letter. The default prefix is Ctrl + b. You press it, release it, then press the command key.
Ctrl+b ? Show all key bindings (help)
Ctrl+b d Detach from the current session
Session Management
# Create a new named session
tmux new -s myproject
tmux new-session -s myproject # Long form
# List all sessions
tmux ls
tmux list-sessions
# Attach to an existing session
tmux attach -t myproject
tmux a -t myproject # Short form
# Detach from a session (back to your normal terminal)
Ctrl+b d
# Kill a session
tmux kill-session -t myproject
# Rename a session (inside tmux)
Ctrl+b $
SSH use case: Start a build or test run inside tmux on a remote server, detach, close your SSH connection, reconnect later and tmux attach — the process kept running.
Window Management
Ctrl+b c Create a new window
Ctrl+b , Rename the current window
Ctrl+b n Move to the next window
Ctrl+b p Move to the previous window
Ctrl+b 0-9 Switch to window by number (0, 1, 2...)
Ctrl+b w Show an interactive list of windows to choose from
Ctrl+b & Kill the current window (with confirmation)
Pane Splitting and Navigation
Ctrl+b % Split current pane vertically (side by side)
Ctrl+b " Split current pane horizontally (top and bottom)
Ctrl+b ←↑↓→ Move focus to the pane in that direction
Ctrl+b q Show pane numbers briefly — press the number to jump
Ctrl+b z Zoom the current pane to full screen (toggle)
Ctrl+b x Kill the current pane (with confirmation)
Ctrl+b { Swap pane with the one above
Ctrl+b } Swap pane with the one below
Resize panes by holding the prefix and using arrow keys:
Ctrl+b (hold) + ←↑↓→ Resize pane in that direction
Or in command mode (Ctrl+b :):
:resize-pane -D 5 Move border down 5 cells
:resize-pane -L 10 Move border left 10 cells
Practical Workflows
Development setup in one session:
tmux new -s myapp
# Window 1: editor (already open)
# Split horizontally for server
Ctrl+b "
# Top pane: open your editor
vim src/app.ts
# Bottom pane: start dev server
npm run dev
# Create Window 2 for tests
Ctrl+b c
npm run test:watch
# Create Window 3 for git
Ctrl+b c
git status
Copy text from a pane:
Ctrl+b [ Enter copy mode (scroll and select)
Space Start selection (vi mode)
Enter Copy selection
Ctrl+b ] Paste copied text
q Exit copy mode
~/.tmux.conf Basics
Tmux is highly configurable via ~/.tmux.conf. Here are the most commonly useful settings:
# ~/.tmux.conf
# Enable mouse support (click to select panes, scroll output)
set -g mouse on
# Increase scrollback buffer size (default is 2000 lines)
set -g history-limit 50000
# Start windows and panes at 1 (easier to reach on keyboard)
set -g base-index 1
setw -g pane-base-index 1
# Renumber windows when one is closed
set -g renumber-windows on
# Rebind prefix from Ctrl+b to Ctrl+a (more ergonomic)
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
# Split panes with | and - (more intuitive than % and ")
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %
# Reload config without restarting
bind r source-file ~/.tmux.conf \; display "Config reloaded!"
# Status bar styling
set -g status-bg colour235
set -g status-fg colour136
set -g status-left '#[fg=colour226] #S '
set -g status-right '#[fg=colour136] %H:%M %d-%b '
After saving ~/.tmux.conf, reload inside tmux:
Ctrl+b :source-file ~/.tmux.conf
Or with the r binding added above: Ctrl+a r.
When Tmux Is Worth It
Tmux is useful when your work naturally spans several long-running terminal sessions. A typical development day might include an editor, a web server, test watcher, database shell, logs, and a deployment command. Without tmux, those sessions are scattered across tabs and windows. With tmux, they live in one named workspace.
The biggest benefit is persistence. If your SSH connection drops or your laptop sleeps, the tmux session can keep running on the remote machine. Reattach later and your panes are still there.
A Simple Layout
Start with one session per project. Use one window for the app, one for tests, one for logs, and one for ad hoc commands. Do not create a maze of panes just because tmux can do it. If you cannot remember where things are, the layout is too clever.
Use names. Rename sessions and windows so tmux ls tells you something useful. A session called api and windows called server, tests, and logs are easier to navigate than a list of numbers.
Remote Workflows
Tmux shines on remote servers. Start a session before running a long migration, log tail, build, or diagnostic command. If the network drops, reconnect with SSH and run tmux attach. The process is still there unless the server itself restarted.
This does not mean tmux replaces proper process managers. Do not run production services forever inside tmux. Use it for interactive work, debugging, maintenance, and development sessions.
Common Mistakes
New users often change the prefix key, add many plugins, and build a complex config before learning the defaults. Learn the basic session, window, and pane commands first. Then add customization only when you know what friction you are removing.
Another mistake is leaving dozens of stale sessions running. Clean them up. A tidy tmux environment is easier to reattach to and less likely to hide old processes that confuse your debugging.
What I Would Do In Practice
I would use tmux for remote development, long-running commands, and project workspaces that need several terminal views. I would keep the config small: a comfortable prefix, mouse support if desired, better pane navigation, and a reload binding.
Tmux is not about making the terminal look busy. It is about continuity. When your work survives disconnects and stays organized by project, the tool is doing its job.
Troubleshooting Tmux Confusion
If tmux feels disorienting, print the hierarchy in your head: session, window, pane. A session is the project workspace. A window is a task area. A pane is a split inside that task. Most confusion comes from creating too many panes before the session and window structure is clear.
When shortcuts stop working, check whether the command belongs to tmux, your shell, or the program running inside the pane. For example, scrolling inside tmux may require copy mode, while scrolling inside an editor is handled by the editor. The active layer matters.
Keep one short reference note with your prefix key, split commands, pane movement, detach, attach, and session listing. Once those commands are automatic, tmux becomes much calmer.
Pair Tmux With Project Scripts
Tmux organizes terminals, but it should not hide how a project runs. Keep the real commands in package.json, a Makefile, or project documentation, then use tmux panes to run them side by side. That way a teammate can still start the app without knowing your tmux layout.
For a web project, one window for the server, one for tests, one for logs, and one for ad hoc commands is usually enough. Add complexity only when the project earns it.