starmorph logo
Published on

Tmux Terminal Multiplexer Guide: Master Multi-Pane Workflows for Developers

Tmux Terminal Multiplexer Guide: Master Multi-Pane Workflows for Developers

If you've ever SSH'd into a server, started a process, and lost it when your connection dropped — or wished you could watch logs, monitor system stats, and type commands all in one terminal window — tmux is the tool you need. Tmux (Terminal Multiplexer) lets you run multiple terminal sessions inside a single window, persist them across disconnects, and split your screen into any layout you can imagine.

This guide covers everything from basic tmux concepts to advanced tmuxinator automation, giving you a complete toolkit for efficient terminal workflows on servers and local machines alike.

v0 banner

Table of Contents

What is Tmux?

Tmux is a terminal multiplexer — a program that lets you run multiple terminal sessions inside a single window. Three features make it essential for developers and sysadmins:

  • Persistent sessions — Detach and reattach without losing running processes. SSH disconnects no longer kill your work.
  • Multiple panes — Split your terminal into panels showing different things simultaneously. Watch logs in one pane while editing code in another.
  • Remote-friendly — SSH into a server, start tmux, detach, disconnect. Come back hours later, tmux attach — everything is still running exactly where you left it.

If you work with remote servers, run long-running processes, or want a more efficient terminal workflow, tmux is a game-changer.

Installation

# Ubuntu / Debian
sudo apt update && sudo apt install tmux

# macOS
brew install tmux

# CentOS / RHEL / Fedora
sudo dnf install tmux    # Fedora / RHEL 8+
sudo yum install tmux    # CentOS 7

# Verify installation
tmux -V

Core Concepts

Tmux organizes everything in a 3-level hierarchy:

Session (top level — a named workspace)
  └── Window (like a browser tab)
       └── Pane (a split within a window)

Think of it like this: a session is your project workspace, windows are tabs within that workspace, and panes are split views within each tab.

The Prefix Key

Almost every tmux command starts with the prefix key combo, which defaults to:

Ctrl + b

You press Ctrl+b, release both keys, then press the next key. For example, Ctrl+b then % splits the pane vertically.

Throughout this guide, <prefix> means Ctrl+b unless you've remapped it (we'll cover that in the configuration section).

Sessions

Sessions are the top-level container. You typically have one session per project or task.

ActionCommand
Start new sessiontmux or tmux new -s myname
Detach from session<prefix> d
List sessionstmux ls
Attach to sessiontmux attach -t myname
Attach to last sessiontmux attach or tmux a
Rename session<prefix> $
Kill sessiontmux kill-session -t myname
Switch sessions<prefix> s (interactive list)
Next / prev session<prefix> ( / <prefix> )

Detach is the killer feature for remote work. SSH into a server, start tmux, run your processes, detach with Ctrl+b d, disconnect SSH entirely. Come back later, run tmux attach — everything is still running. No more losing work to dropped connections.

Windows

Windows are like tabs within a session. Use them to organize different tasks.

ActionKey Binding
Create new window<prefix> c
Next window<prefix> n
Previous window<prefix> p
Go to window N<prefix> 0-9
List windows (interactive)<prefix> w
Rename window<prefix> ,
Close window<prefix> & (confirms) or exit in last pane

A typical workflow: one window for logs, one for system stats, one for an active shell. Press Ctrl+b 1 through Ctrl+b 3 to jump between them instantly.

Panes

Panes are the splits within a window. This is where tmux really shines for monitoring and multitasking.

Creating Panes

ActionKey BindingMnemonic
Split vertically (left/right)<prefix> %% looks like two columns
Split horizontally (top/bottom)<prefix> "" looks like two rows

Here's how to create a 4-pane grid step by step:

1. Start tmux:           tmux new -s monitoring
2. Split vertically:     Ctrl+b %      → [left | right]
3. Split left horiz:     Ctrl+b "      → [top-left / bottom-left | right]
4. Move to right pane:   Ctrl+b →
5. Split right horiz:    Ctrl+b "      → 4-pane grid

Result:

┌──────────┬──────────┐
│  pane 0  │  pane 2  │
├──────────┤──────────┤
│  pane 1  │  pane 3  │
└──────────┴──────────┘
ActionKey Binding
Move to pane (arrow keys)<prefix> ←↑↓→
Cycle to next pane<prefix> o
Go to previous pane<prefix> ;
Show pane numbers<prefix> q (then press number to jump)

Resizing Panes

ActionKey Binding
Resize in direction<prefix> Ctrl+←↑↓→ (hold Ctrl, tap arrow)
Resize by 5 cells<prefix> Alt+←↑↓→

Or from the command prompt (<prefix> :):

resize-pane -D 10    # down 10 rows
resize-pane -U 5     # up 5 rows
resize-pane -L 10    # left 10 cols
resize-pane -R 10    # right 10 cols

Other Pane Operations

ActionKey Binding
Zoom pane (fullscreen toggle)<prefix> z
Close pane<prefix> x (confirms) or type exit
Swap pane forward<prefix> }
Swap pane backward<prefix> {
Rotate panes<prefix> Ctrl+o
Break pane into new window<prefix> !
Toggle pane layouts<prefix> Space

Zoom is essential for monitoring. Press <prefix> z to expand one pane full-screen to read a long log, then <prefix> z again to snap back to your grid layout.

Copy Mode

When logs scroll past faster than you can read, you need to scroll back and search through output.

ActionKey Binding
Enter copy mode<prefix> [
Scroll up/downArrow keys or PgUp/PgDn
Search forward/ then type pattern
Search backward? then type pattern
Next matchn
Start selectionSpace
Copy selectionEnter
Paste<prefix> ]
Exit copy modeq or Esc

Copy mode uses vim-style navigation by default. Once you enter copy mode with <prefix> [, you can scroll freely through the pane's history buffer, search for specific strings, and copy text to paste elsewhere.

Configuration

Create ~/.tmux.conf to customize tmux behavior. Changes apply on next tmux start, or reload live with:

tmux source-file ~/.tmux.conf
# --- Better prefix (Ctrl+a instead of Ctrl+b) ---
# Closer to the home row, easier to reach
unbind C-b
set -g prefix C-a
bind C-a send-prefix

# --- Mouse support ---
# Click panes to select, scroll with mouse wheel, resize by dragging
set -g mouse on

# --- Start window/pane numbering at 1 ---
set -g base-index 1
setw -g pane-base-index 1

# --- Intuitive split keys ---
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
unbind '"'
unbind %

# --- Vim-style pane navigation ---
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

# --- Faster pane resizing ---
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

# --- Longer scrollback buffer ---
set -g history-limit 50000

# --- Don't auto-rename windows ---
set -g allow-rename off

# --- Status bar ---
set -g status-style bg=colour235,fg=colour136
set -g status-interval 5

# --- Reload config shortcut ---
bind r source-file ~/.tmux.conf \; display "Config reloaded!"

With this config:

  • Ctrl+a | splits vertically (left/right)
  • Ctrl+a - splits horizontally (top/bottom)
  • Ctrl+a h/j/k/l navigates panes vim-style
  • Mouse works for clicking, scrolling, and resizing pane borders
  • New panes open in the same directory as the current pane

Tmuxinator: Automated Session Management

Once you have a tmux layout you use regularly, manually recreating it every time gets tedious. Tmuxinator solves this — define your layout once in YAML, then launch it with a single command.

Installing Tmuxinator

# Via RubyGems (works everywhere)
gem install tmuxinator

# Via Homebrew (macOS)
brew install tmuxinator

# Via apt (Ubuntu/Debian)
sudo apt install tmuxinator

Requirements: tmux >= 1.8, Ruby >= 2.6 (for gem install), and $EDITOR set in your environment.

Creating a Tmuxinator Project

# Create a new project config
tmuxinator new monitoring

# This opens your editor with a template at:
#   ~/.config/tmuxinator/monitoring.yml

YAML Config Structure

Here's an annotated example:

# ~/.config/tmuxinator/monitoring.yml
name: monitoring
root: ~/

on_project_start: echo "Starting monitoring session..."

windows:
  # Window 1: Log monitoring (3 panes side by side)
  - logs:
      layout: even-horizontal
      panes:
        - tail -f /var/log/syslog
        - tail -f /var/log/auth.log
        - journalctl -f

  # Window 2: System stats (grid layout)
  - stats:
      layout: main-vertical
      panes:
        - htop
        - watch -n 2 df -h
        - watch -n 5 free -m

  # Window 3: Clean shell for ad-hoc commands
  - shell:

Run tmuxinator start monitoring and everything opens automatically — windows, panes, and commands all running.

Available Layouts

LayoutDescription
even-horizontalEqual columns side by side
even-verticalEqual rows stacked vertically
main-horizontalOne large pane on top, rest below
main-verticalOne large pane on left, rest stacked right
tiledEqual-size grid

You can also capture custom layout strings from a running tmux session:

tmux list-windows -F "#{window_layout}"

Config Fields Reference

FieldPurpose
nameSession name in tmux
rootDefault working directory for all panes
on_project_startShell commands run once before session creation
on_project_stopShell commands run when stopping the project
on_project_exitShell commands run on detach or stop
pre_windowCommands run in every pane before its own commands
startup_windowWhich window to focus on start
startup_paneWhich pane to focus on start

Managing Tmuxinator Projects

ActionCommand
Create new projecttmuxinator new myproject
Start projecttmuxinator start myproject
Stop project (kill session)tmuxinator stop myproject
List projectstmuxinator list
Edit project configtmuxinator edit myproject
Delete projecttmuxinator delete myproject
Copy projecttmuxinator copy old new
Debug configtmuxinator debug myproject

Tip: Alias mux to tmuxinator in your shell config for faster access:

alias mux='tmuxinator'

Passing Arguments

Tmuxinator supports ERB templating for dynamic configs:

name: monitoring
root: <%= @args[0] || "~/" %>

windows:
  - logs:
      panes:
        - tail -f <%= @args[1] || "/var/log/syslog" %>
tmuxinator start monitoring /home/deploy /var/log/app.log

Local Project Configs

Keep a .tmuxinator.yml in a project directory for project-specific layouts:

# In your project root:
tmuxinator local

# Creates ./.tmuxinator.yml
# Start with:
tmuxinator start   # uses local config automatically

Practical VM Monitoring Setup

Here's a production-ready tmuxinator config for monitoring a server:

# ~/.config/tmuxinator/vm-monitor.yml
name: vm-monitor
root: ~/

on_project_start: echo "VM Monitor started at $(date)"

windows:
  # Window 1: Application logs
  - app-logs:
      layout: even-vertical
      panes:
        - tail -f /var/log/app/production.log
        - tail -f /var/log/nginx/access.log
        - tail -f /var/log/nginx/error.log

  # Window 2: System monitoring (grid)
  - system:
      layout: tiled
      panes:
        - htop
        - watch -n 2 'df -h'
        - watch -n 5 'free -h'
        - watch -n 3 'ss -tuln'

  # Window 3: Docker containers
  - docker:
      layout: main-vertical
      panes:
        - docker stats
        - watch -n 5 'docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"'
        - docker logs -f --tail 50 my-app-container

  # Window 4: Network & security
  - network:
      layout: even-horizontal
      panes:
        - watch -n 10 'netstat -an | grep ESTABLISHED | wc -l'
        - tail -f /var/log/auth.log
        - journalctl -f -u ssh

  # Window 5: Clean shell
  - shell:

Start it up:

tmuxinator start vm-monitor

Workflow Tips

  1. Switch windows: Ctrl+b 1 through Ctrl+b 5 to jump between monitoring views
  2. Zoom a pane: Ctrl+b z to expand one log full-screen, press again to snap back
  3. Scroll logs: Ctrl+b [ to enter copy mode, scroll up, / to search
  4. Detach safely: Ctrl+b d — monitoring continues running even after you disconnect SSH
  5. Come back later: tmux attach or tmuxinator start vm-monitor (reattaches if already running)

Quick One-Liner (No Tmuxinator)

If you want a quick 4-pane monitoring setup without tmuxinator:

tmux new-session -s monitor \; \
  split-window -h \; \
  split-window -v \; \
  select-pane -t 0 \; \
  split-window -v \; \
  select-pane -t 0 \; \
  send-keys 'tail -f /var/log/syslog' Enter \; \
  select-pane -t 1 \; \
  send-keys 'htop' Enter \; \
  select-pane -t 2 \; \
  send-keys 'tail -f /var/log/auth.log' Enter \; \
  select-pane -t 3 \; \
  send-keys 'watch df -h' Enter

Quick Reference

Tmux Cheat Sheet

CategoryActionKey Binding
SessionsCreate named sessiontmux new -s name
Attach to sessiontmux a -t name
List sessionstmux ls
Detach<prefix> d
Switch sessions<prefix> s
WindowsNew window<prefix> c
Next / previous<prefix> n / <prefix> p
Go to window N<prefix> 0-9
List (interactive)<prefix> w
Rename<prefix> ,
PanesSplit vertical<prefix> %
Split horizontal<prefix> "
Navigate<prefix> ←↑↓→
Zoom (toggle)<prefix> z
Close pane<prefix> x
Show pane numbers<prefix> q
Cycle layouts<prefix> Space
Copy ModeEnter copy mode<prefix> [
Search fwd / back/ or ?
Exit copy modeq

Tmuxinator Cheat Sheet

ActionCommand
Create configtmuxinator new NAME
Start sessiontmuxinator start NAME
Stop sessiontmuxinator stop NAME
Edit configtmuxinator edit NAME
List all configstmuxinator list
Delete configtmuxinator delete NAME
Duplicate configtmuxinator copy OLD NEW
Debug generated cmdstmuxinator debug NAME
Create local configtmuxinator local

Tmux vs Tmuxinator

FeatureTmux (Manual)Tmuxinator (Automated)
Setup effortBuild layout by hand each timeDefine once in YAML, launch with one command
FlexibilityFull control in real-timePre-defined layouts, less ad-hoc
Best forQuick ad-hoc splits, one-off useRepeatable setups you use daily
Learning curveMemorize key bindingsLearn YAML config format
RecommendationLearn this firstUse this for daily workflows

Start by learning tmux basics — sessions, panes, and navigation. Once you have a layout you use regularly, capture it in a tmuxinator config so you can recreate your entire workspace with a single command on any machine. The combination of persistent sessions and automated layouts makes tmux one of the most powerful productivity tools in a developer's toolkit.