The first time it bit me I was halfway through a database migration over SSH. Train hit a tunnel, WiFi blinked, connection gone. The process running on the other end went with it. I sat there staring at a dead prompt wondering how much of the migration had actually committed.

A terminal multiplexer would have saved me. The process keeps running on the server whether I’m attached or not, so a dropped connection becomes a non-event. I reconnect, reattach, and the work is exactly where I left it. That property alone is worth the setup cost, and it’s why I treat a multiplexer as part of the base layer on every machine I touch.

I should say up front where I’m coming from, because it colours everything below. I’m terminal-first, keyboard-first, and I’ve been driving tmux for years. That bias is real. I’ve spent serious time in all three of the big options though, so I can be fair about where each one wins.

What Is a Terminal Multiplexer?

A multiplexer sits between your shell and your terminal emulator. It owns the session, and your terminal window is just a viewport onto it. Detach the viewport and the session keeps humming along on its own. That single layer of indirection gives you four things:

  • Session persistence: Detach, reconnect later, everything still running
  • Screen splits: Multiple panes in one window
  • Window management: Switch between workspaces
  • Remote parity: Same interface whether you’re local or SSH’d into a box on the other side of the country
flowchart LR
    Term["Terminal Emulator"] --> Mux["Multiplexer"]
    Mux --> Shell1["Shell 1"]
    Mux --> Shell2["Shell 2"]
    Mux --> Shell3["Shell 3"]

Before I walk through the three, here’s what I actually judge them on. Not feature count, because every one of them can split a screen. The things that matter day to day are: how likely the tool is to already be installed when I land on a strange box, how much config I need to write before it’s usable, whether I can discover commands without a cheat sheet, and how far I can script it. Performance barely registers; they’re all light enough on modern hardware. Keep those four criteria in mind as I go.

GNU Screen: The Original

Screen has been around since 1987. It’s installed everywhere, it works, and it looks like it was designed in 1987.

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

What Screen has going for it is that it’s already there. On a hardened box, a vendor appliance, a rescue shell, some ancient Solaris machine a client forgot existed, Screen is often the only multiplexer present and you can’t install anything else. It’s stable precisely because nobody’s touched it in years, and it does the attach/detach job without fuss.

The cost shows up the moment you want more than that. There’s no visual feedback, the key bindings are cryptic, the splits are “regions” rather than real panes, and scrollback inside a split is a mess when you’re trying to read through a log. None of this matters for a quick detach. All of it matters if Screen is your daily driver, which is why almost nobody chooses it as one anymore.

So I keep Screen in the back pocket for exactly one situation: a server I don’t control where I can’t install software and I just need a process to survive my connection. For everything else I reach for something newer.

tmux: The Standard

tmux is what most people reached for once they wanted more than Screen could give. More features, a better interface, and active development. It’s also the one I actually live in, so read the rest with that in mind.

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

The default tmux experience is genuinely awkward, and this is the honest knock against it. Out of the box the prefix is Ctrl-b, the splits are unintuitive, and you’ll fight the muscle memory you built in Screen. tmux pays you back for the config work though. Here’s a practical ~/.tmux.conf that fixes the worst of the defaults:

# 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

Where tmux earns its keep is configurability and scripting. Everything is adjustable, the plugin ecosystem covers anything you’d want, and the scripting story is the real prize: I can describe a whole working session in a shell script and recreate it identically anywhere. That maps straight onto how I think about infrastructure, where the config is written down and reproducible instead of clicked together once and forgotten. The trade is the learning curve and the up-front config tax. You don’t get a nice tmux for free, you build one.

Zellij: The Modern Option

Zellij is the newcomer. Written in Rust, and built around the idea that you shouldn’t need to memorise anything to use it.

Basic Usage

# Start new session
zellij

# Start named session
zellij -s development

# Attach to session
zellij attach development

# List sessions
zellij list-sessions

The thing that sets Zellij apart is that it shows you the keybindings as you go. The status bar tells you what’s available in the current mode, so you find your way around by looking instead of by remembering. For anyone who has ever stared blankly at a terminal trying to recall the tmux split binding, that’s a real quality-of-life win.

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

Every mode advertises its actions in the status bar, so discoverability is baked in rather than bolted on.

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"; }
}

Zellij’s defaults are sensible, the layouts are reusable, and floating panes for a quick throwaway command are lovely. The catches are that it’s young, so the plugin ecosystem is thin compared to tmux, you have to install it yourself, and if you come from tmux your muscle memory fights you for a week. None of those are dealbreakers. They’re the normal price of a newer tool that hasn’t been everywhere for fifteen years yet.

Comparison

FeatureScreentmuxZellij
Learning curveMediumHighLow
ConfigurationMinimalExtensiveGood
Default UXPoorPoorGood
Plugin supportNoneExcellentGrowing
AvailabilityEverywhereMost placesInstall required
Session persistenceYesYes (plugins)Yes
ScriptingBasicExcellentGood
PerformanceLightMediumMedium
DevelopmentMinimalActiveActive

My Workflow

So which one did I actually land on? tmux, every day. Here’s the setup behind that choice.

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?

The honest answer is mostly path dependence. Years of tmux muscle memory, a plugin setup (resurrect and continuum) I’d have to rebuild, scripted sessions I rely on, and the fact that tmux is on every server I touch. Switching would cost more than it’d pay back.

I want to be clear that this isn’t me saying tmux is the better tool in the abstract. If I were starting from zero today, with no muscle memory to protect, I’d give Zellij a hard look. The discoverability is genuinely better, and watching newcomers pick it up in an afternoon makes the case on its own. My choice is about my context, not a verdict on yours.

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

Keeping a process alive through a dropped connection is the obvious win, and it’s the one I opened with. The reason a multiplexer stays on every machine I own runs deeper than that. It changes how the work feels. Each project gets its own session, so context lives somewhere persistent instead of in my head. Windows and panes become places, and after a while my hands know that logs are bottom-right and the editor is window one without my brain getting involved. Nothing pulls me out of flow to go hunt for a window.

Pair a multiplexer with an editor and shell you’ve tuned, and you get a working environment that’s identical on your laptop and on any server you SSH into. That portability is the whole point for me. I’m not helpless on a fresh box, because the same muscle memory works everywhere, and the config travels in a git repo I control rather than living trapped in some GUI’s settings.

The terminal is already low friction computing. A good multiplexer drops the friction lower still, until the tool itself stops registering and you’re just working.