tmux Configuration Guide for Security and AI Dev
Posted: April 14, 2026 to Technology.
tmux is the single most important terminal tool in our cybersecurity and AI development workflow. It is the foundation that makes everything else possible: persistent sessions that survive SSH disconnects, multi-pane layouts for monitoring parallel processes, and scriptable environments that reproduce complex setups in a single command. At Petronella Technology Group, every engineer on our team runs tmux on every machine, from local NixOS workstations to remote GPU servers. This guide documents the exact configuration patterns we use daily for security assessments, AI model training, and infrastructure management.
If you have ever lost a long-running process because your SSH connection dropped, or found yourself opening six terminal windows to monitor different parts of a system, tmux solves both problems permanently. This is not a theoretical overview. Every configuration snippet in this guide comes from production use across our team.
Why tmux Matters for Professional Workflows
Terminal multiplexers are not a convenience. For anyone who works on remote servers, runs long processes, or manages complex multi-tool workflows, tmux is infrastructure. Here is what it gives you.
Session persistence. tmux sessions continue running on the server regardless of what happens to your client connection. If your SSH drops, your VPN reconnects, or your Wayland compositor crashes, every process inside tmux keeps running. You reconnect and reattach. Nothing is lost. We have had AI training runs survive network outages, power blips on laptops, and even full workstation reboots because the training was running inside tmux on a remote GPU server.
Multi-pane layouts. A single terminal window can display four, six, or eight separate shell sessions arranged in any configuration you choose. During a security assessment, we run nmap in one pane, watch authentication logs in another, review results in a third, and keep a notes buffer in a fourth. All visible simultaneously, all in a single tmux window. No alt-tabbing, no hunting for the right terminal.
Scriptable environments. tmux can be driven entirely through shell commands. That means you can write a script that creates a session, splits it into panes, sends specific commands to each pane, and arranges them into a predefined layout. We have scripts for every common work context: security audit, AI training, development, and infrastructure monitoring. One command sets up the entire workspace.
Collaboration. Multiple users can attach to the same tmux session simultaneously. During pair programming or incident response, two engineers can share a terminal session in real time. This is faster than screen sharing and works over any SSH connection, regardless of bandwidth.
Installation Across Platforms
Ubuntu / Debian
sudo apt update && sudo apt install tmux
Ubuntu 24.04 ships tmux 3.4. For the latest release, build from source or use a PPA. The version matters because features like popup windows, extended keys, and improved copy mode were added in recent releases.
NixOS (Declarative)
On NixOS, tmux is typically managed through Home Manager for per-user configuration:
# home.nix
programs.tmux = {
enable = true;
terminal = "tmux-256color";
escapeTime = 0;
historyLimit = 50000;
keyMode = "vi";
mouse = true;
prefix = "C-a";
baseIndex = 1;
plugins = with pkgs.tmuxPlugins; [
sensible
yank
resurrect
continuum
vim-tmux-navigator
];
extraConfig = ''
# Custom config loaded from Nix
set -g status-style "bg=#1a1b26,fg=#c0caf5"
set -g renumber-windows on
'';
};
The advantage of declaring tmux through Nix is that every workstation in the fleet gets an identical configuration. When we onboard a new machine, the tmux setup is already there after nixos-rebuild switch.
macOS
brew install tmux
On macOS, clipboard integration requires additional configuration (covered in the copy/paste section below). The reattach-to-user-namespace workaround is no longer needed on modern macOS versions with tmux 3.2+.
Building from Source
git clone https://github.com/tmux/tmux.git
cd tmux
sh autogen.sh
./configure
make && sudo make install
Building from source is useful when you need a specific version for feature compatibility. tmux depends on libevent and ncurses. Install libevent-dev and libncurses-dev on Debian-based systems before building.
Core Concepts: Sessions, Windows, and Panes
tmux has three layers of organization. Understanding these is essential before touching configuration.
Sessions are the top-level container. A session persists until you explicitly kill it or the server shuts down. You can have multiple sessions running simultaneously, each representing a different project or work context. We typically run separate sessions for each client engagement, each named descriptively: client-acme-audit, gpu-training, infra-monitoring.
Windows live inside sessions. A window occupies the full terminal area and behaves like a tab. You switch between windows within a session. We name windows by purpose: code, logs, ssh, notes.
Panes divide a window into rectangular regions, each running its own shell. Panes let you see multiple processes at once. A common layout is a large editing pane on the left with two smaller monitoring panes stacked on the right.
The prefix key is how you tell tmux that the next keystroke is a tmux command rather than input to the running program. The default prefix is Ctrl+b. You press Ctrl+b, release, then press the command key. For example, Ctrl+b c creates a new window, Ctrl+b % splits the pane vertically, and Ctrl+b " splits horizontally.
Essential commands for beginners:
# Start a new named session
tmux new-session -s work
# Detach from current session (prefix + d)
# Ctrl+b d
# List all sessions
tmux list-sessions
# Reattach to a named session
tmux attach-session -t work
# Kill a session
tmux kill-session -t work
# Create a new window (prefix + c)
# Ctrl+b c
# Split pane vertically (prefix + %)
# Ctrl+b %
# Split pane horizontally (prefix + ")
# Ctrl+b "
# Navigate between panes (prefix + arrow keys)
# Ctrl+b Left/Right/Up/Down
# Cycle through windows (prefix + n / prefix + p)
# Ctrl+b n (next)
# Ctrl+b p (previous)
Our tmux Configuration
This section covers the specific customizations we run at Petronella. Each change solves a real problem we encountered in daily use.
Custom Prefix Key: Ctrl+a
The Ctrl+b default prefix requires an awkward hand stretch. Ctrl+a is faster to type because both keys sit on the left side of the keyboard. The tradeoff is that Ctrl+a is the readline shortcut for "go to beginning of line" in bash. We solve this by binding Ctrl+a a to send a literal Ctrl+a to the underlying shell when needed.
# Change prefix from Ctrl+b to Ctrl+a
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# Double-tap Ctrl+a to send literal Ctrl+a
bind a send-prefix
Some engineers on our team use Ctrl+Space as the prefix instead. This avoids conflicting with any readline binding and feels natural. The choice is personal, but pick something that does not collide with your most-used shortcuts.
Vi-Mode Keybindings for Copy and Paste
tmux has a built-in copy mode that lets you scroll through terminal output and select text. By default, it uses emacs-style keybindings. We switch to vi mode because our team uses Neovim with Nerd Fonts as the primary editor, and consistent keybindings across tools reduce friction.
# Vi mode for copy
setw -g mode-keys vi
# Enter copy mode with prefix + [
# Navigate with h/j/k/l
# Start selection with v
# Copy selection with y
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "wl-copy"
bind -T copy-mode-vi C-v send-keys -X rectangle-toggle
# Paste with prefix + P (capital P to avoid conflict with previous-window)
bind P paste-buffer
# Also copy to system clipboard on mouse selection
bind -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "wl-copy"
On Wayland, wl-copy handles clipboard integration. On X11, substitute xclip -selection clipboard. On macOS, use pbcopy. The copy-pipe-and-cancel action copies the selection and exits copy mode in a single step.
Mouse Support
Enabling mouse support lets you click to select panes, drag to resize pane borders, and scroll with the mouse wheel to enter copy mode. Some terminal purists disable mouse support entirely. We enable it because not every team member is a keyboard-only user, and it makes onboarding faster.
# Enable mouse support
set -g mouse on
# Scroll wheel enters copy mode
bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'select-pane -t=; copy-mode -e; send-keys -M'"
Pane Navigation with Vim-Like hjkl Bindings
Instead of using arrow keys or the default pane-switching bindings, we use h, j, k, l for pane navigation. This keeps your hands on the home row and aligns with Vim muscle memory.
# Pane navigation (prefix + h/j/k/l)
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Pane resizing (prefix + H/J/K/L)
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
# Split panes with more intuitive keys
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
unbind '"'
unbind %
The -c "#{pane_current_path}" flag ensures new panes open in the same directory as the current pane. Without this, every new pane starts in the home directory, which is never what you want during active work.
Status Bar Configuration
The status bar is your information dashboard. We configure it to show the session name, window list, git branch, system load, and GPU utilization. The Tokyo Night color scheme keeps it consistent with our terminal and editor theme.
# Status bar position and refresh
set -g status-position bottom
set -g status-interval 5
set -g status-justify left
# Tokyo Night color scheme
set -g status-style "bg=#1a1b26,fg=#c0caf5"
set -g window-status-current-style "bg=#7aa2f7,fg=#1a1b26,bold"
set -g window-status-style "fg=#565f89"
set -g pane-border-style "fg=#3b4261"
set -g pane-active-border-style "fg=#7aa2f7"
set -g message-style "bg=#1a1b26,fg=#7aa2f7"
# Left side: session name
set -g status-left-length 40
set -g status-left "#[fg=#7aa2f7,bold] #S #[fg=#565f89]| "
# Right side: git branch + system stats + time
set -g status-right-length 100
set -g status-right "#[fg=#9ece6a]#{?#{pane_current_path},#(cd #{pane_current_path} && git branch --show-current 2>/dev/null),} #[fg=#565f89]| #[fg=#bb9af7]#(cat /proc/loadavg | awk '{print $1}') #[fg=#565f89]| #[fg=#e0af68]%H:%M "
# Window numbering
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
# Window format
set -g window-status-format " #I:#W "
set -g window-status-current-format " #I:#W "
For machines with NVIDIA GPUs, we add GPU utilization to the status bar. This is invaluable during AI training runs when you want a constant read on GPU usage without switching to a separate monitoring pane:
# GPU utilization in status bar (NVIDIA only)
# Requires nvidia-smi
set -g status-right "#[fg=#9ece6a]GPU:#(nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits)%% #[fg=#565f89]| #[fg=#e0af68]VRAM:#(nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits)MiB #[fg=#565f89]| #[fg=#bb9af7]#(cat /proc/loadavg | awk '{print $1}') #[fg=#565f89]| #[fg=#c0caf5]%H:%M "
General Quality-of-Life Settings
# 256 color and true color support
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",*256col*:Tc"
set -ga terminal-overrides ",xterm-kitty:Tc"
set -ga terminal-overrides ",alacritty:Tc"
# Reduce escape delay (critical for Neovim)
set -sg escape-time 0
# Increase scrollback buffer
set -g history-limit 50000
# Focus events for Neovim autoread
set -g focus-events on
# Activity monitoring
setw -g monitor-activity on
set -g visual-activity off
# Do not rename windows automatically
set -g allow-rename off
# Quick reload of config
bind r source-file ~/.tmux.conf \; display-message "Config reloaded"
tmux for AI Development
AI development has specific requirements that tmux handles exceptionally well. Model training runs last hours or days. You cannot afford to lose them to a network hiccup. You need simultaneous visibility into multiple metrics. And you frequently work on remote GPU servers over SSH.
Monitoring GPU Utilization in a Persistent Pane
The standard approach is to run nvidia-smi in watch mode in a dedicated pane:
# In a tmux pane, run:
watch -n 1 nvidia-smi
# Or for a more compact view:
watch -n 1 'nvidia-smi --query-gpu=index,name,temperature.gpu,utilization.gpu,memory.used,memory.total --format=csv'
# For multi-GPU systems, nvitop provides a better interface:
pip install nvitop
nvitop
We keep this running in a small pane on the right side of the window. The GPU pane stays visible regardless of what we are doing in the main editing pane. When a training run is consuming more VRAM than expected or GPU utilization drops (indicating a data loading bottleneck), we see it immediately.
Long Training Runs That Survive Disconnects
This is the core value of tmux for AI work. Start a training job inside a tmux session on a remote GPU server, detach, close your laptop, go home, and reattach the next morning. The training continues uninterrupted.
# SSH into GPU server
ssh ptg-rtx
# Create or attach to training session
tmux new-session -A -s training
# Start training (this persists even if SSH drops)
python train.py --model llama-3.2 --epochs 50 --batch-size 16 2>&1 | tee training.log
# Detach: Ctrl+a d
# Close terminal, go home
# Later: ssh ptg-rtx && tmux attach -t training
The -A flag in tmux new-session -A -s training attaches to the session if it already exists, or creates it if it does not. This is safer than separate new/attach commands because you never accidentally create a duplicate session.
Split-Pane Layout for AI Work
Our standard AI development layout uses four panes:
# Top-left (60% width): Code editor (Neovim)
# Top-right (40% width): Model output / training logs
# Bottom-left (60% width): Python REPL / testing
# Bottom-right (40% width): GPU stats (nvidia-smi or nvitop)
# Create this layout with a script:
tmux new-session -d -s ai -n code
tmux split-window -h -t ai:code -p 40
tmux split-window -v -t ai:code.1 -p 30
tmux split-window -v -t ai:code.2 -p 50
tmux send-keys -t ai:code.1 'nvim .' C-m
tmux send-keys -t ai:code.2 'tail -f training.log' C-m
tmux send-keys -t ai:code.3 'python3' C-m
tmux send-keys -t ai:code.4 'nvitop' C-m
tmux select-pane -t ai:code.1
tmux attach -t ai
tmux with SSH Tunnels for Remote GPU Servers
When running TensorBoard, Jupyter, or Grafana on a remote GPU server, SSH tunnels forward the web interface to your local browser. tmux keeps the tunnel alive even if you switch contexts:
# In a dedicated tmux window called "tunnels":
ssh -L 6006:localhost:6006 -L 8888:localhost:8888 ptg-rtx -N
# Port 6006: TensorBoard
# Port 8888: Jupyter
# The -N flag means no remote command, just tunneling
# This stays alive inside tmux even if your local terminal closes
We maintain a "tunnels" window in our AI session specifically for this. It runs SSH with port forwarding and nothing else. Keeping tunnels in their own window means you never accidentally close them when cleaning up panes. For details on our AI infrastructure, including the GPU fleet we manage for training and inference, see our AI services page.
tmux for Cybersecurity Work
Security assessments involve running multiple tools simultaneously, capturing everything for audit trails, and maintaining secure session handling. tmux is built for this workflow.
Parallel Tool Monitoring During Assessments
A typical penetration test or vulnerability assessment requires watching output from several tools at once: network scanning, service enumeration, credential testing, and documentation. In a tmux layout, all of these run in separate panes within a single window, and you can watch them progress in real time.
# Assessment layout:
# Left (50%): Active scanning tool
# Top-right (25%): Wireshark/tcpdump
# Bottom-right (25%): Notes/documentation
tmux new-session -d -s audit -n recon
tmux split-window -h -t audit:recon -p 50
tmux split-window -v -t audit:recon.2 -p 50
# Window 2: Exploitation
tmux new-window -t audit -n exploit
# Window 3: Evidence and reporting
tmux new-window -t audit -n evidence
tmux select-window -t audit:recon
tmux attach -t audit
Session Logging for Audit Trails
For compliance engagements (CMMC, HIPAA, PCI), you need a complete record of every command executed during an assessment. tmux can log all pane output to files automatically:
# Enable logging for the current pane (prefix + Shift+P)
bind P pipe-pane -o "cat >> $HOME/tmux-logs/#{session_name}-#{window_name}-#{pane_index}-%Y%m%d-%H%M%S.log" \; display-message "Logging toggled"
# Or start logging when creating the session:
tmux pipe-pane -t audit:recon.1 -o "cat >> ~/audit-logs/recon-scan-$(date +%Y%m%d).log"
Every keystroke and every line of output gets written to timestamped log files. These become part of the assessment evidence package. The pipe-pane approach captures the raw terminal output, including tool banners and timestamps, exactly as they appeared during the engagement.
Secure Session Handling
tmux sessions are accessible through a Unix socket. By default, the socket is created in /tmp with permissions restricted to the owning user. For shared systems, verify the socket permissions:
# Check tmux socket location and permissions
ls -la /tmp/tmux-$(id -u)/
# For extra isolation, use a custom socket in your home directory
tmux -S ~/.tmux-secure-socket new-session -s classified
# Set restrictive permissions
chmod 700 ~/.tmux-secure-socket
On shared servers, always use named sessions with meaningful names. Never leave unnamed sessions running that other administrators might inadvertently attach to. When handling sensitive data during assessments, consider using a custom socket path in a directory with restricted permissions rather than the default /tmp location.
For additional security, destroy sessions immediately when work is complete rather than leaving them running:
# Kill the session and all its processes when done
tmux kill-session -t client-audit
# Verify no sessions remain
tmux list-sessions
Session Templates for Different Work Contexts
We maintain shell scripts that create preconfigured tmux sessions for common work patterns. One command sets up the entire workspace. Here are three templates we use daily.
Security Audit Layout
#!/usr/bin/env bash
# ~/bin/tmux-audit.sh
SESSION="audit-$(date +%Y%m%d)"
tmux new-session -d -s "$SESSION" -n recon
tmux send-keys -t "$SESSION:recon" "mkdir -p ~/audit-logs/$SESSION && cd ~/audit-logs/$SESSION" C-m
# Recon window: scanning + packet capture + notes
tmux split-window -h -t "$SESSION:recon" -p 40
tmux split-window -v -t "$SESSION:recon.2" -p 50
# Exploit window
tmux new-window -t "$SESSION" -n exploit
tmux split-window -h -t "$SESSION:exploit" -p 50
# Evidence window
tmux new-window -t "$SESSION" -n evidence
tmux send-keys -t "$SESSION:evidence" "cd ~/audit-logs/$SESSION" C-m
# Reporting window
tmux new-window -t "$SESSION" -n report
# Enable logging on recon panes
tmux pipe-pane -t "$SESSION:recon.1" -o "cat >> ~/audit-logs/$SESSION/recon-main.log"
tmux pipe-pane -t "$SESSION:recon.2" -o "cat >> ~/audit-logs/$SESSION/recon-secondary.log"
tmux select-window -t "$SESSION:recon"
tmux select-pane -t "$SESSION:recon.1"
tmux attach -t "$SESSION"
AI Training Monitor
#!/usr/bin/env bash
# ~/bin/tmux-ai.sh
SESSION="ai-train"
tmux new-session -d -s "$SESSION" -n training
tmux send-keys -t "$SESSION:training" "cd ~/projects/model-training" C-m
# Training window: code + logs + GPU
tmux split-window -h -t "$SESSION:training" -p 35
tmux split-window -v -t "$SESSION:training.2" -p 40
tmux send-keys -t "$SESSION:training.3" "watch -n 2 nvidia-smi" C-m
# Data window: dataset prep + validation
tmux new-window -t "$SESSION" -n data
# Eval window: model evaluation + benchmarks
tmux new-window -t "$SESSION" -n eval
# Tunnels window: TensorBoard + Jupyter forwarding
tmux new-window -t "$SESSION" -n tunnels
tmux select-window -t "$SESSION:training"
tmux attach -t "$SESSION"
Development Layout
#!/usr/bin/env bash
# ~/bin/tmux-dev.sh
SESSION="dev"
tmux new-session -d -s "$SESSION" -n code
tmux send-keys -t "$SESSION:code" "nvim ." C-m
# Code window: editor + terminal + git
tmux split-window -v -t "$SESSION:code" -p 30
tmux split-window -h -t "$SESSION:code.2" -p 50
tmux send-keys -t "$SESSION:code.3" "lazygit" C-m
# Servers window: dev server + test runner
tmux new-window -t "$SESSION" -n servers
tmux split-window -h -t "$SESSION:servers" -p 50
# SSH window: remote connections
tmux new-window -t "$SESSION" -n ssh
tmux select-window -t "$SESSION:code"
tmux select-pane -t "$SESSION:code.1"
tmux attach -t "$SESSION"
Plugin Ecosystem: TPM, Resurrect, Continuum, and Yank
tmux has a mature plugin ecosystem managed through TPM (Tmux Plugin Manager). Plugins extend tmux without modifying its core, and TPM handles installation and updates.
Installing TPM
# Clone TPM into the plugins directory
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
# Add to .tmux.conf:
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
# Initialize TPM (must be at the very bottom of .tmux.conf)
run '~/.tmux/plugins/tpm/tpm'
# Install plugins: prefix + I (capital i)
# Update plugins: prefix + U
# Remove unused plugins: prefix + alt + u
tmux-resurrect: Save and Restore Sessions
tmux-resurrect saves the complete state of your tmux environment (sessions, windows, panes, working directories, and running programs) and restores it after a server restart. This is the plugin that makes tmux sessions truly persistent across reboots.
set -g @plugin 'tmux-plugins/tmux-resurrect'
# Restore Neovim sessions
set -g @resurrect-strategy-nvim 'session'
# Capture pane contents
set -g @resurrect-capture-pane-contents 'on'
# Save: prefix + Ctrl+s
# Restore: prefix + Ctrl+r
tmux-continuum: Automatic Save and Restore
tmux-continuum automates what tmux-resurrect does manually. It saves your environment at regular intervals and automatically restores the last saved state when tmux starts.
set -g @plugin 'tmux-plugins/tmux-continuum'
# Auto-save every 15 minutes
set -g @continuum-save-interval '15'
# Auto-restore on tmux start
set -g @continuum-restore 'on'
# Show save status in status bar
set -g status-right '#{continuum_status}'
With resurrect and continuum together, you can reboot a workstation and come back to the exact tmux layout you had before. Pane positions, window names, working directories, and even some running programs are restored.
tmux-yank: System Clipboard Integration
tmux-yank provides seamless copy-to-clipboard functionality across platforms. It detects your clipboard tool (wl-copy on Wayland, xclip on X11, pbcopy on macOS) and handles the integration automatically.
set -g @plugin 'tmux-plugins/tmux-yank'
# Remain in copy mode after yanking
set -g @yank_action 'copy-pipe'
vim-tmux-navigator: Seamless Neovim Integration
This plugin allows you to navigate between Neovim splits and tmux panes using the same Ctrl+h/j/k/l keybindings. Without it, you need separate keybindings for moving between Neovim windows and tmux panes. With it, navigation is transparent: Ctrl+l moves right whether you are inside Neovim or in tmux.
set -g @plugin 'christoomey/vim-tmux-navigator'
# In your Neovim config (init.lua), add the matching plugin:
# { "christoomey/vim-tmux-navigator" }
tmux vs Alternatives: Zellij, Screen, and Built-In Multiplexing
| Feature | tmux | Zellij | GNU Screen | Kitty Splits |
|---|---|---|---|---|
| Language | C | Rust | C | C/Python |
| Session Persistence | Yes | Yes | Yes | No |
| Plugin System | TPM (mature) | WASM plugins | None | Kittens (Python) |
| Scripting | Excellent | Good (layouts) | Basic | Python API |
| Learning Curve | Steep | Gentle | Steep | Minimal |
| True Color | Yes (3.2+) | Yes | Limited | Yes |
| Remote Use (SSH) | Excellent | Excellent | Excellent | N/A (local only) |
| Community Size | Very large | Growing | Legacy | Medium |
| Multi-User Attach | Yes | Yes | Yes | No |
| Best For | Power users, servers | Beginners, modern UX | Legacy systems | Local-only workflows |
Zellij is the most compelling alternative. It is written in Rust, has built-in layout management with KDL configuration, and provides a discoverable UI with on-screen keybinding hints. If you are new to terminal multiplexers, Zellij is genuinely easier to learn. Where tmux wins is in its scripting capabilities, ecosystem maturity, and universal availability. tmux is installed on virtually every Linux server you will ever SSH into. Zellij usually is not. For remote work on servers you do not control, tmux is the practical choice.
GNU Screen is tmux's predecessor. It does session persistence and basic splitting, but it has not kept pace with modern terminal features. True color support is incomplete, the configuration syntax is arcane, and the project receives minimal updates. There is no reason to choose Screen over tmux for new setups. The only scenario where Screen makes sense is on ancient systems where tmux is not available and you cannot install packages.
Built-in terminal multiplexing from terminals like Kitty, WezTerm, or Alacritty provides pane splitting without a separate tool. These work well for local development but do not persist across SSH disconnects and do not run on remote servers. They complement tmux rather than replace it. We use Kitty as our terminal emulator and tmux inside it for session management.
Performance Tips and Terminal Compatibility
Escape Time: The Most Important Setting
tmux introduces a delay after the Escape key to distinguish between a bare Escape press and an escape sequence. The default delay is 500 milliseconds. In Neovim, this means pressing Escape to exit insert mode has a half-second lag. Setting escape-time to 0 eliminates this delay entirely:
set -sg escape-time 0
If you use Neovim or Vim inside tmux and have ever felt that mode switching is sluggish, this single setting fixes it. It is the first thing we add to any tmux configuration.
Terminal Type and True Color
Incorrect terminal type settings cause color rendering issues, broken special characters, and cursor shape problems. The correct configuration depends on your terminal emulator:
# Set tmux's default terminal
set -g default-terminal "tmux-256color"
# Override for specific terminals to enable true color
set -ga terminal-overrides ",xterm-256color:Tc"
set -ga terminal-overrides ",xterm-kitty:Tc"
set -ga terminal-overrides ",alacritty:Tc"
# Enable cursor shape changes (for Neovim)
set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q'
Test true color support with this command inside tmux:
awk 'BEGIN{
for (colnum = 0; colnum < 77; colnum++) {
r = 255-(colnum*255/76);
g = (colnum*510/76);
b = (colnum*255/76);
if (g > 255) g = 510-g;
printf "\033[48;2;%d;%d;%dm", r, g, b;
printf "\033[38;2;%d;%d;%dm", 255-r, 255-g, 255-b;
printf "%s\033[0m", substr(".", colnum+1, 1);
}
printf "\n";
}'
You should see a smooth color gradient. If you see banding or blocks of the same color, your terminal override settings need adjustment.
Scrollback Buffer Size
The default scrollback is 2,000 lines. For security work and AI development, where tool output can be extremely verbose, we set it to 50,000:
set -g history-limit 50000
Be aware that very large scrollback buffers consume memory proportional to the number of panes you have open. On a machine with dozens of panes, 50,000 lines per pane adds up. For most workflows, 50,000 is a reasonable balance between having enough history and not consuming excessive RAM.
Integration with Neovim, fzf, and Lazygit
Neovim Integration
The combination of tmux and Neovim is the core of our development environment. vim-tmux-navigator (mentioned in the plugins section) provides seamless pane/split navigation. Additional integration points:
# In Neovim init.lua:
-- Ensure tmux sends correct key sequences
vim.opt.termguicolors = true
-- Auto-reload files changed outside Neovim (triggered by tmux focus events)
vim.opt.autoread = true
vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter" }, {
command = "checktime",
})
The focus-events setting in tmux (mentioned earlier) sends focus gained/lost events to programs inside tmux. Neovim uses these to trigger autoread, which reloads files that were modified externally. This means if you edit a file in one pane and switch to Neovim in another, Neovim picks up the changes automatically.
fzf Integration
fzf (fuzzy finder) integrates with tmux to provide popup selection menus. You can search files, git branches, processes, and command history through a tmux popup overlay:
# In .bashrc or .zshrc, enable tmux popup for fzf
export FZF_TMUX=1
export FZF_TMUX_OPTS="-p 80%,60%"
# tmux-fzf plugin for session/window/pane switching
set -g @plugin 'sainnhe/tmux-fzf'
With fzf-tmux, pressing Ctrl+r for reverse history search opens a floating popup inside tmux rather than replacing the current pane content. This feels native and does not disrupt your visible layout.
Lazygit Integration
Lazygit is a terminal UI for git that provides staging, committing, branching, and rebasing through a keyboard-driven interface. We run lazygit in a dedicated tmux pane alongside the code editor:
# Quick toggle: open lazygit in a tmux popup
bind g display-popup -d "#{pane_current_path}" -w 80% -h 80% -E "lazygit"
This binding opens lazygit as a floating popup over your current tmux window. Press q to close lazygit and the popup disappears, returning you to your original layout. It is faster than switching to a dedicated lazygit pane because you do not lose your visual context.
Publishing Our Configuration
We publish our tmux configs at github.com/capetron. The repository includes our complete .tmux.conf, session template scripts, and NixOS Home Manager declarations. If you want to start from a tested, production configuration rather than building one from scratch, clone the repo and adjust to your preferences.
Frequently Asked Questions
How do I fix tmux colors looking wrong or washed out?
This is almost always a terminal type mismatch. Set default-terminal to "tmux-256color" and add terminal-overrides for your specific terminal emulator to enable true color (Tc). Run the color gradient test script from the performance section to verify. If colors still look wrong, check that your terminal emulator itself is configured for true color output.
Can I use tmux on a remote server without installing plugins?
Yes. Plugins are optional. A well-configured .tmux.conf without any plugins covers 90% of use cases. Plugins add convenience (session persistence across reboots, clipboard integration, fuzzy finding) but are not required. When working on servers where you cannot install TPM, copy just the .tmux.conf file and skip the plugin lines.
What is the difference between detaching and killing a session?
Detaching (prefix + d) disconnects your terminal from the session while the session and all its processes continue running. You can reattach later. Killing a session (tmux kill-session -t name) terminates the session and all processes inside it. Detach when you want to come back. Kill when you are done.
How do I share a tmux session with another user for pair programming?
Both users SSH into the same server. One creates the session, the other attaches with tmux attach -t session-name. Both users see the same panes and can type simultaneously. For users with different accounts, create a shared socket: tmux -S /tmp/shared-session new-session and set permissions so both users can access the socket file. Pair programming through tmux works over any network connection, even on slow links where screen sharing would be unusable.
Should I use tmux inside tmux (nested sessions)?
This happens naturally when you SSH from a local tmux session into a remote server running its own tmux. The solution is to use a different prefix key on the remote instance or use send-prefix to forward commands to the inner tmux. Press the prefix key twice: the first sends it to the local tmux, the second sends a literal prefix to the remote tmux. Some users remap the remote prefix to Ctrl+b while keeping Ctrl+a locally, making it clear which session receives each command.
How much memory does tmux use?
The tmux server process itself uses minimal memory (typically 5-15 MB). Memory consumption scales with the number of panes and the scrollback buffer size per pane. With our recommended 50,000 line scrollback and 10-15 active panes, total memory usage for the tmux server stays under 100 MB. This is negligible on any modern workstation or server.
Does tmux work with clipboard on Wayland?
Yes, but it requires configuration. tmux itself does not interact with the system clipboard directly. You configure copy mode to pipe selections to wl-copy (Wayland) or xclip (X11). The tmux-yank plugin automates this detection. If you are using Hyprland or niri as your compositor, wl-copy from the wl-clipboard package handles clipboard integration.
Getting Started
The fastest path to a productive tmux setup: install tmux, create ~/.tmux.conf with the configuration from this guide, and start a named session with tmux new-session -s work. Learn the prefix key, pane splitting, and window creation first. Add plugins and session templates once the basics are second nature. The investment in learning tmux pays for itself the first time a long-running process survives a dropped SSH connection.
If your team handles sensitive data, runs AI workloads on GPU servers, or manages infrastructure across multiple machines, tmux is not optional. It is the layer that makes everything above it reliable. At Petronella, it runs on every machine we operate, from local development workstations to production GPU servers.
For organizations that need help building secure development environments, configuring GPU infrastructure for AI workloads, or implementing compliance-ready workflows, contact our team at (919) 348-4912.
About the Author: Craig Petronella is the CEO of Petronella Technology Group, a cybersecurity and IT infrastructure firm in Raleigh, NC. With CMMC-RP, CCNA, CWNE, and DFE certifications and over 30 years in IT, Craig’s team uses tmux daily across every workstation and server for security assessments, AI development, and client infrastructure management.