You SSH into a server. You start a long-running process. Your connection drops. Process dies.
Terminal multiplexers solve this. They keep sessions alive, split your screen into panes, and let you work on multiple things without opening twelve terminal windows.
I’ve used all three major options. Here’s what I learned.
What Is a Terminal Multiplexer?
A terminal multiplexer runs between your shell and terminal emulator. It:
- Persists sessions: Detach, reconnect later, everything still running
- Splits screens: Multiple panes in one window
- Manages windows: Switch between workspaces
- Works remotely: Same interface whether local or SSH’d
flowchart LR
Term["Terminal Emulator"] --> Mux["Multiplexer"]
Mux --> Shell1["Shell 1"]
Mux --> Shell2["Shell 2"]
Mux --> Shell3["Shell 3"]
GNU Screen: The Original
Screen has been around since 1987. It’s installed everywhere, it works, it’s ugly.
Basic Usage
# Start new session
screen
# Start named session
screen -S development
# Detach (from inside screen)
Ctrl-a d
# List sessions
screen -ls
# Reattach
screen -r development
# Split horizontally
Ctrl-a S
# Split vertically
Ctrl-a |
# Switch between regions
Ctrl-a Tab
# Create new window
Ctrl-a c
# Switch windows
Ctrl-a n # next
Ctrl-a p # previous
Ctrl-a 0 # window 0
Strengths
- Ubiquitous: Installed on almost every Unix system
- Stable: Hasn’t changed much because it doesn’t need to
- Simple: Does what it says, nothing more
Weaknesses
- Dated interface: No visual feedback, cryptic key bindings
- Limited splits: Splits are regions, not true panes
- No scrollback in splits: Annoying when debugging
When to Use Screen
- Server without anything else installed
- Quick attach/detach for long processes
- Systems where you can’t install software
tmux: The Standard
tmux replaced Screen for most users. More features, better interface, active development.
Basic Usage
# Start new session
tmux
# Start named session
tmux new -s development
# Detach
Ctrl-b d
# List sessions
tmux ls
# Attach
tmux attach -t development
# Split horizontally
Ctrl-b "
# Split vertically
Ctrl-b %
# Navigate panes
Ctrl-b Arrow keys
# Resize panes
Ctrl-b Ctrl-Arrow keys
# Create window
Ctrl-b c
# Switch windows
Ctrl-b n # next
Ctrl-b p # previous
Ctrl-b 0 # window 0
# Kill pane
Ctrl-b x
Configuration
tmux shines with configuration. Here’s a practical ~/.tmux.conf:
# Better prefix
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# Start windows and panes at 1, not 0
set -g base-index 1
setw -g pane-base-index 1
# Renumber windows when one is closed
set -g renumber-windows on
# Easy splits (more intuitive)
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
# Vim-style pane navigation
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Resize panes with vim keys
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
# Mouse support (optional, some prefer keyboard-only)
set -g mouse on
# Increase scrollback
set -g history-limit 50000
# Don't wait for escape sequences
set -sg escape-time 0
# Status bar
set -g status-style 'bg=#333333 fg=#ffffff'
set -g status-left '#[fg=#00ff00][#S] '
set -g status-right '%H:%M %d-%b'
# Reload config
bind r source-file ~/.tmux.conf \; display "Config reloaded"
Plugin Manager (TPM)
Install TPM for plugins:
# Install TPM
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
# In .tmux.conf
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-resurrect' # Save/restore sessions
set -g @plugin 'tmux-plugins/tmux-continuum' # Auto-save sessions
# Initialize TPM (at bottom of .tmux.conf)
run '~/.tmux/plugins/tpm/tpm'
Press prefix + I to install plugins.
Session Management
Save and restore sessions:
# With tmux-resurrect plugin
prefix + Ctrl-s # Save
prefix + Ctrl-r # Restore
# Manual session scripts
# ~/.tmux/dev-session.sh
tmux new-session -d -s dev -n editor
tmux send-keys -t dev:editor 'nvim' C-m
tmux new-window -t dev -n server
tmux send-keys -t dev:server 'npm run dev' C-m
tmux new-window -t dev -n git
tmux attach -t dev
Strengths
- Highly configurable: Everything is adjustable
- Plugin ecosystem: Extensions for everything
- Scriptable: Automate session creation
- Active development: Regular updates, new features
Weaknesses
- Learning curve: Default bindings are awkward
- Requires configuration: Not great out of the box
- Resource usage: Heavier than Screen
Zellij: The Modern Option
Zellij is the newest option. Written in Rust, designed for usability.
Basic Usage
# Start new session
zellij
# Start named session
zellij -s development
# Attach to session
zellij attach development
# List sessions
zellij list-sessions
The key difference: Zellij shows you the keybindings. No memorization required.
Default Keybindings
Zellij uses a modal system:
Ctrl-p → Pane mode
n: new pane
d: close pane
h/j/k/l: navigate
Ctrl-t → Tab mode
n: new tab
x: close tab
h/l: navigate
r: rename
Ctrl-n → Resize mode
h/j/k/l: resize
Ctrl-s → Scroll mode
j/k: scroll
d/u: page down/up
Ctrl-o → Session mode
d: detach
w: session manager
Ctrl-q → Quit
The status bar shows available actions. Huge for discoverability.
Configuration
~/.config/zellij/config.kdl:
// Theme
theme "catppuccin-mocha"
// Default layout
default_layout "compact"
// Keybindings
keybinds {
normal {
// Vim-like pane navigation
bind "Alt h" { MoveFocus "Left"; }
bind "Alt j" { MoveFocus "Down"; }
bind "Alt k" { MoveFocus "Up"; }
bind "Alt l" { MoveFocus "Right"; }
}
}
// Options
pane_frames false // No borders between panes
simplified_ui true // Cleaner status bar
default_shell "zsh"
scrollback_editor "/usr/bin/nvim"
Layouts
Define reusable layouts in ~/.config/zellij/layouts/:
// dev.kdl
layout {
pane split_direction="vertical" {
pane {
command "nvim"
}
pane split_direction="horizontal" {
pane {
command "lazygit"
}
pane
}
}
}
Start with layout:
zellij --layout dev
Plugins
Zellij supports WebAssembly plugins:
// In config.kdl
plugins {
tab-bar { path "tab-bar"; }
status-bar { path "status-bar"; }
strider { path "strider"; } // File browser
compact-bar { path "compact-bar"; }
}
Strengths
- Discoverable: Keybindings shown in UI
- Modern: Good defaults, sensible design
- Layouts: Define and reuse workspace layouts
- Floating panes: Overlay panes for quick tasks
Weaknesses
- Newer: Less ecosystem, fewer plugins
- Not everywhere: Need to install it
- Different paradigm: Existing muscle memory doesn’t transfer
Comparison
| Feature | Screen | tmux | Zellij |
|---|---|---|---|
| Learning curve | Medium | High | Low |
| Configuration | Minimal | Extensive | Good |
| Default UX | Poor | Poor | Good |
| Plugin support | None | Excellent | Growing |
| Availability | Everywhere | Most places | Install required |
| Session persistence | Yes | Yes (plugins) | Yes |
| Scripting | Basic | Excellent | Good |
| Performance | Light | Medium | Medium |
| Development | Minimal | Active | Active |
My Workflow
I use tmux daily. Here’s my setup:
Config Philosophy
# Minimal, keyboard-first
# Ctrl-a as prefix (easier than Ctrl-b)
# Vim-style navigation
# No mouse (keeps hands on keyboard)
# Minimal status bar
Session Structure
Development session:
├── Window 1: editor (nvim)
├── Window 2: terminal (general commands)
├── Window 3: git (lazygit)
└── Window 4: servers (split panes for logs)
Homelab session:
├── Window 1: k9s (Kubernetes)
├── Window 2: monitoring (Prometheus/Grafana access)
└── Window 3: logs (Loki queries)
Startup Script
#!/bin/bash
# ~/.local/bin/dev
SESSION="dev"
# Check if session exists
tmux has-session -t $SESSION 2>/dev/null
if [ $? != 0 ]; then
# Create session
tmux new-session -d -s $SESSION -n editor
tmux send-keys -t $SESSION:editor 'nvim' C-m
tmux new-window -t $SESSION -n term
tmux new-window -t $SESSION -n git
tmux send-keys -t $SESSION:git 'lazygit' C-m
tmux new-window -t $SESSION -n servers
tmux split-window -h -t $SESSION:servers
fi
# Attach
tmux attach -t $SESSION
Why tmux Over Zellij?
For me:
- Muscle memory (years of tmux)
- Plugin ecosystem (resurrect, continuum)
- Scriptability (complex session automation)
- Available on all my servers
If starting fresh today, I might choose Zellij. The discoverability is genuinely better.
Recommendations
Choose Screen if:
- Working on servers you don’t control
- Need something that’s definitely installed
- Simple attach/detach for long processes
Choose tmux if:
- You want maximum customization
- You need plugin support
- You’ll invest time in configuration
- You work across many machines
Choose Zellij if:
- You’re new to multiplexers
- You want good UX immediately
- You prefer modern tooling
- You value discoverability
Getting Started
Week 1: Learn Basics
Pick one. Learn these operations:
- Create/attach/detach session
- Split panes
- Navigate between panes
- Create windows
- Navigate between windows
Week 2: Configure
Make it yours:
- Change prefix key (tmux/Screen)
- Set up comfortable keybindings
- Configure status bar
- Set scrollback size
Week 3: Integrate
Build into workflow:
- Create session scripts
- Set up session persistence
- Integrate with editor/shell
Why This Matters
Terminal multiplexers aren’t just for keeping processes alive. They change how you work:
- Context preservation: Each project gets a session
- Spatial memory: Windows and panes become places
- Flow state: Everything in one place, no window switching
Combined with a good editor and shell, you have a complete development environment that works identically on your laptop and any server you SSH into.
The terminal is low friction computing. Multiplexers make it even lower.
The best tool is the one that disappears. A good multiplexer becomes invisible — just part of how you think about working.
