I used to be a tmux power user.

This was back in my Linux Systems Engineer days. I lived in terminals connected to servers in three different data centers. I had tmux sessions named by function: web, db, monitoring. Each one was a perfectly arranged grid of panes that survived disconnection, reboot, and the occasional 3 AM page. I didn’t think about the prefix key any more than I thought about the spacebar. It was just how terminals worked.

Then I moved into engineering leadership. More time in browsers and meetings, less in terminals. And tmux went quiet. I didn’t uninstall it. I just stopped needing it.

Fast forward to 2026. I’m running Hermes Agent in the terminal. Multiple concurrent instances, each doing different work: one handling research, one managing code review, one running a kanban backlog. They’re all CLI processes. They all produce output I need to see. They all run at the same time.

I tried tabs. But tabs only show you one thing at a time, and I needed to watch several agents work in parallel. I tried separate terminal windows, but my desktop quickly devolved into a tile manager’s worst nightmare: a dozen windows overlapping, none where I left them, the Dock an unreadable mess of nearly identical terminal icons.

I needed tmux back. And the beautiful thing is, tmux hadn’t gone anywhere. It was still there, still maintained by Nicholas Marriott, still the same rock-solid terminal multiplexer it’s always been. Version 3.6b had actually been released just days before I sat down to write this — the project isn’t dead, it just moves at its own deliberate pace. When a release lands, it lands with substance: scrollbars, native scrollback integration, proper clipboard handling. And then it goes quiet again, because it doesn’t need to chase trends.

I just had to relearn it. And this time, I decided to do it properly and write down everything I wish someone had shown me the first time around.

This is that guide. It’s for anyone who’s ever had too many terminals open and wished for a better way.

The Problem That Only tmux Solves#

Before we get into keystrokes and config files, let’s be clear about what tmux actually does that nothing else does well.

Session persistence. You can disconnect from a tmux session: close your laptop, lose your WiFi, kill your terminal emulator. Every process running inside tmux stays alive. You reconnect later, and everything is exactly where you left it. Terminal tabs don’t do this. Terminal windows don’t do this. Even iTerm2’s “restore window” feature only works if the application doesn’t crash.

Arbitrary splitting. You can divide your terminal into panes: side by side, stacked, tiled, in any arrangement you want. Resize them independently. You can have a Hermes agent running in one pane, a log tail in another, htop in a third. All visible at once, all independently scrollable.

The three-level hierarchy. tmux organizes your terminal work into sessions, windows, and panes. A session is a complete workspace: one project, one context. A window is like a tab within that session. A pane is a split within a window. This scales from “I have one thing running” to “I have a dozen things and I know exactly where each one is.”

There are newer tools that try to solve parts of this problem: Zellij with its mouse-friendly interface, Beam with its Electron-based workspace concept. They’re fine. But tmux works everywhere, has no GUI dependencies, runs over SSH without a second thought, and is installed on basically every Unix system you’ll ever touch.

Your First Session#

If you’re on macOS, the install is one command:

brew install tmux

(Linux: apt install tmux or your distro’s equivalent. Windows: WSL2, then apt install tmux.)

Now type tmux. That’s it. You’re in.

You’ll notice a green status bar at the bottom of your terminal. That’s tmux’s command center: it shows your windows on the left, the time and system info on the right. It’s completely customizable, but we’ll get to that.

Right now you’re in a single pane in a single window in a single session. Let’s fix that.

The Prefix Key#

Every tmux command starts with a key combination called the prefix. The default is Ctrl+b: you press and release Ctrl+b, then press the command key. It’s like a namespace: Ctrl+b tells tmux “the next key is for you, not for the shell.”

This is going to feel awkward for about an hour. Then it’ll feel like second nature. Don’t skip the awkward phase.

Splitting Panes#

Let’s split your terminal in half:

  • Split vertically (left/right): Ctrl+b then %
  • Split horizontally (top/bottom): Ctrl+b then " (the double-quote key)

Try both. Split your terminal into a 2x2 grid. Congratulations: you’re now running four shells in one window.

To move between panes, use Ctrl+b followed by an arrow key pointing in the direction you want to go. Ctrl+b + right moves to the pane on your right. Ctrl+b + up moves to the pane above.

To resize a pane, Ctrl+b then press and hold Ctrl while pressing the arrow keys. This one takes some practice: the resize speed can feel slow at first, but you get used to it.

Don’t like the layout you ended up with? Ctrl+b + spacebar cycles through tmux’s built-in presets: even-horizontal, even-vertical, main-horizontal, main-vertical, and tiled. Keep pressing spacebar to see them all.

Windows#

If panes are splits within a view, windows are whole new views. Think of them like tabs.

  • Create a new window: Ctrl+b then c
  • Next window: Ctrl+b then n
  • Previous window: Ctrl+b then p
  • Go to window by number: Ctrl+b then the number (0, 1, 2: or 1, 2, 3 once we configure it)

Your status bar now shows both windows. The active one has a * next to it.

Sessions#

Sessions are the top level of tmux’s hierarchy. If windows are tabs and panes are splits, sessions are like browser windows: completely independent workspaces.

Here’s the most important thing you can do right now: name your sessions.

tmux new -s hermes-research

This creates a new session called hermes-research. Later, you can attach to it by name:

tmux attach -t hermes-research

To see all running sessions:

tmux ls

Inside tmux, detach from your current session with Ctrl+b then d. Everything keeps running. Come back whenever you want.

To switch between sessions without detaching, Ctrl+b then s: this opens an interactive session picker. Arrow keys to navigate, Enter to select.

Killing Things#

  • Kill a pane: Type exit in the shell, or Ctrl+b then x and confirm
  • Kill a window: Ctrl+b then & and confirm
  • Kill a session (from outside): tmux kill-session -t session-name

Your First .tmux.conf#

Out of the box, tmux is functional but rough. A few configuration changes make it sing. Here’s a starter config that I use. Every line has a job:

# ~/.tmux.conf: the only tmux config file you need to know about

# Mouse support: click to focus, drag to resize, scroll to history
set -g mouse on

# Start numbering at 1 instead of 0 (humans don't count from zero)
set -g base-index 1
setw -g pane-base-index 1

# Renumber windows when one closes (no gaps in the numbering)
set -g renumber-windows on

# 10000 lines of scrollback per pane
set -g history-limit 10000

# Enable 24-bit color (if your terminal supports it: iTerm2 does)
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",*256col*:Tc"

# Reduce escape-time to 10ms (critical for vim/neovim users)
set -sg escape-time 10

# Vi-style copy mode (you'll thank me later)
setw -g mode-keys vi

# Faster key repeat
set -g repeat-time 300

# Status bar: refresh every 15 seconds
set -g status-interval 15

Loading your config. To apply changes without restarting tmux:

tmux source-file ~/.tmux.conf

Or from inside tmux: Ctrl+b then :source-file ~/.tmux.conf

What These Settings Actually Do#

Let me call out the ones that matter most, because I’ve seen too many blog posts just dump a config with no explanation.

mouse on is the single biggest quality-of-life improvement you can make. With it enabled, you can click to focus a pane, drag pane borders to resize, scroll through history with your mouse wheel, and select text. Without it, everything is keyboard-only. Start with it on. Graduate to keyboard-only later if you want.

escape-time 10 matters enormously if you use vim or neovim. When you press Escape in vim, there’s a brief window where tmux can misinterpret it as the start of an escape sequence. The default timeout is 500ms: which means vim feels laggy every time you leave insert mode. Dropping it to 10ms eliminates that lag entirely. Some people set it to 0, but that can cause issues with terminal emulators that send escape sequences slowly. 10 is the sweet spot.

default-terminal "tmux-256color" enables 24-bit color support. Without it, your terminal emulator’s carefully chosen color scheme will look washed out inside tmux. If you’re on macOS with iTerm2, this line is what makes the colors match.

mode-keys vi makes tmux’s copy mode behave like vi instead of emacs. If you know vi keybindings (and even if you only kind of know them), this is more intuitive.

Copy Mode and the macOS Clipboard#

Here’s where most macOS tmux tutorials go wrong.

You need to be able to select text in tmux and paste it into other applications. This is trivially easy on Linux (tmux pipes to xclip or wl-copy). On macOS, there’s a history of workarounds.

The Old Way (Don’t Do This)#

Older tutorials will tell you to install reattach-to-user-namespace and use it as a wrapper for pbcopy:

brew install reattach-to-user-namespace

Then in your .tmux.conf:

bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "reattach-to-user-namespace pbcopy"

This works, but it’s a workaround for a problem that modern terminals have already solved. reattach-to-user-namespace hasn’t had a meaningful update in years, and its install numbers are dropping fast. If you brew install tmux on a modern Mac, you don’t need it.

The Modern Way: OSC 52#

Modern terminal emulators, iTerm2, WezTerm, kitty, Ghostty, and others, support a terminal escape sequence called OSC 52 that lets applications inside the terminal read and write the system clipboard directly.

tmux 3.6 (which you have if you installed via Homebrew) detects OSC 52 support automatically and uses it when available. If your terminal supports it, you don’t need any special configuration: tmux handles clipboard integration through the terminal, which handles the system clipboard.

For iTerm2 users: Go to Settings > General > Selection and check “Applications in terminal may access clipboard.” That’s it. No wrapper, no reattach-to-user-namespace, no extra config.

For Terminal.app users: Apple’s Terminal does not support OSC 52. If you’re committed to Terminal.app, you have two options: install reattach-to-user-namespace (the old way, still works) or switch to a terminal emulator that supports OSC 52.

Copy Mode Configuration#

Here’s the copy mode setup that works across terminals. It’s simple because tmux 3.6 handles the clipboard part for you:

# ~/.tmux.conf: copy mode with vi keys

# Enter copy mode (optional: Ctrl+b [ is default)
bind-key -T prefix Enter copy-mode

# Vi-style selection
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi V send-keys -X select-line
bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle

# Copy to clipboard and exit copy mode
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "pbcopy"

With this config, you enter copy mode with Ctrl+b + [, navigate with vi keys (h/j/k/l), select with v, and yank with y. The selected text goes into both tmux’s internal buffer and your system clipboard.

Daily Workflow Patterns#

Once you’ve got the basics down, here are the patterns that make tmux indispensable.

Zoom Pane: Your Focus Button#

Ctrl+b then z: this makes the current pane fill the entire window. Hit z again to restore the split layout.

I use this constantly. When I want to watch a Hermes agent produce output, I zoom into its pane. When I need to check something in another pane, I zoom back out. It’s the difference between “I have four terminals” and “I have one terminal I’m focusing on with three waiting in the wings.”

Command Mode#

Ctrl+b then : opens a command prompt at the bottom of the window. This is where you type tmux commands directly.

Some I use every session:

:swap-pane -D        # Swap pane down
:swap-pane -U        # Swap pane up
:setw synchronize-panes  # Toggle synchronized typing

setw synchronize-panes deserves special mention. With it on, everything you type goes to every pane in the current window simultaneously. It’s dangerous (one typo, and you’ve run the wrong command on six shells at once). It’s also incredibly powerful when you need to run the same command across multiple environments.

Renaming Windows and Sessions#

  • Rename a window: Ctrl+b then , (comma). Type the new name, press Enter.
  • Rename a session (from inside): Ctrl+b then $. Type the new name.
  • Rename a session (from outside): tmux rename-session -t old-name new-name

This matters more than you think. A session named hermes-code-review tells you exactly what’s in it. A session named 0 tells you nothing.

Window Navigation Shortcuts#

  • Ctrl+b then w: interactive window picker with previews
  • Ctrl+b then f: find window by name (searches across all sessions)
  • Ctrl+b then 0 through 9: jump directly to a numbered window

Leveling Up#

You’ve got the basics. Now let’s make tmux truly yours.

Custom Key Bindings#

The default Ctrl+b prefix is fine, but many power users change it to something easier to reach. Ctrl+a is the most common alternative: it’s what GNU Screen used, so it’s familiar to old-timers:

unbind C-b
set -g prefix C-a
bind C-a send-prefix

The tradeoff: Ctrl+a is also “go to beginning of line” in your shell. You’ll need to press Ctrl+a twice to get that behavior: once to send the prefix to tmux (which ignores it because no command follows), then again for the shell. Some people find this annoying. Try both.

Here are some useful custom bindings:

# Easier config reload
bind r source-file ~/.tmux.conf \; display "Config reloaded"

# Quick horizontal/vertical splits
bind | split-window -h
bind - split-window -v

# Vim-style pane navigation (hold Ctrl, press h/j/k/l)
bind -r h select-pane -L
bind -r j select-pane -D
bind -r k select-pane -U
bind -r l select-pane -R

# Alt+arrows for resize (no prefix needed)
bind -n M-Left resize-pane -L 3
bind -n M-Right resize-pane -R 3
bind -n M-Up resize-pane -U 3
bind -n M-Down resize-pane -D 3

The -n flag on the last four means “no prefix required”: just press Alt and the arrow key. Use this sparingly. Once you start using -n bindings, you have to remember which keys are reserved for tmux and which pass through to the shell. I keep it limited to resize operations because those are frequent and the prefix key makes them feel sluggish.

Status Bar Customization#

The default green status bar tells you what you need but doesn’t win any beauty contests. Here’s a config that cleans it up:

# Status bar colors
set -g status-style "bg=#1a1a2e,fg=#e0e0e0"
set -g message-style "bg=#16213e,fg=#e0e0e0"

# Left side: session name
set -g status-left "#[fg=#0f3460,bg=#16213e] #S "
set -g status-left-style "bg=#16213e,fg=#e0e0e0"

# Right side: date and time
set -g status-right "#[fg=#0f3460] %Y-%m-%d %H:%M "

# Window list format
setw -g window-status-current-style "bg=#533483,fg=#e0e0e0"
setw -g window-status-format " #I:#W "
setw -g window-status-current-format " #I:#W "

I keep my status bar minimal: session name on the left, time on the right, windows in the middle. Some people load it up with system info (battery, load average, weather). In my experience, the more you put on the status bar, the less you actually read it. Pick three things and stop.

Multi-line status bar (tmux 3.4+). You can have up to five status lines with set -g status 2. Each line gets its own format via status-format[0], status-format[1], and so on. I use two lines, one for session info, one for window list, and it’s a game changer when you have more than four windows.

Plugins: What You Actually Need#

The Tmux Plugin Manager (TPM) is the standard way to install tmux plugins. It works like a package manager: declare plugins in your config, install with a keybinding, update with another.

To install TPM:

git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

Add to your .tmux.conf:

# Plugin list
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @plugin 'tmux-plugins/tmux-yank'

# Initialize TPM (keep this at the very bottom of the file)
run '~/.tmux/plugins/tpm/tpm'

Install plugins by pressing Ctrl+b then I (capital I) inside tmux.

Three plugins worth your time:

tmux-resurrect saves and restores tmux sessions across reboots. Layouts, working directories, pane contents: everything comes back. After a kernel update forces a reboot, tmux resurrect restores your entire workspace.

tmux-continuum automates resurrect. It saves your session state every 15 minutes and auto-restores when tmux starts. Install it and forget that tmux sessions are supposed to die.

tmux-yank improves clipboard integration. On macOS, it uses pbcopy under the hood, so selections go to the system clipboard without additional config.

Popups and Menus#

tmux 3.2 introduced display-popup, which opens a floating terminal overlay. tmux 3.3 added display-menu, which opens a context menu. These don’t get enough attention.

# Ctrl+b + M opens a popup at 80% width/height
bind M display-popup -w 80 -h 80

# Ctrl+b + Ctrl+p shows a quick action menu
bind C-p display-menu -T "Quick Actions" \
  "Rename Window"  r "command-prompt -I '#W' {rename-window '%%'}" \
  "Kill Window"    k "kill-window" \
  "New Session"    n "command-prompt {new-session -s '%%'}"

The popup is perfect for quick commands: run a git command in a popup, dismiss it, and you’re back to your layout without disturbing any pane. The menu is great for actions you don’t use often enough to memorize the keybinding.

Scripting tmux#

You can script tmux from the command line. This sets up a standard workspace:

#!/bin/bash
SESSION="hermes"

# Create the session with a first window
tmux new-session -d -s "$SESSION" -n "research"

# Add more windows
tmux new-window -t "$SESSION" -n "code-review"
tmux new-window -t "$SESSION" -n "kanban"
tmux new-window -t "$SESSION" -n "logs"

# Split the logs window into two panes
tmux split-window -h -t "$SESSION:logs"

# Attach
tmux attach-session -t "$SESSION"

Save this as ~/bin/tmux-hermes.sh, make it executable with chmod +x, and you have a one-command workspace setup.

For more complex session management, check out tmuxp: it lets you define sessions in YAML files and load them with one command.

The Hermes Workflow#

This is where all of it comes together.

I run Hermes Agent in the terminal with hermes chat for interactive sessions and hermes gateway for long-running background processes. Each instance is a long-lived process that produces output, accepts input, and needs to be visible when I’m interacting with it.

Here’s my daily layout:

Session: hermes-main

  • Window 1: agent: an interactive hermes chat session
  • Window 2: gateway: the hermes gateway process, showing webhook traffic
  • Window 3: kanban: kanban board status (hermes kanban list)
  • Window 4: logs: split into two panes: gateway logs and agent logs

Session: hermes-background

  • Window 1: cron: cron job execution output
  • Window 2: cashew: thought-graph sync worker output

Session: dev

  • Window 1: code: my editor
  • Window 2: tests: running test suite
  • Window 3: git: git operations and PR management

I switch between sessions with Ctrl+b then s (the interactive picker). When I’m deep in the hermes-main session, I zoom into whichever agent pane needs attention, then zoom back to see the full layout.

At the end of the day, I detach from everything with a single command:

tmux detach-client -a

This detaches all clients except the current one. Close the terminal. Everything keeps running.

In the morning: tmux attach -t hermes-main. Everything is exactly where I left it.

One More Thing: iTerm2 Integration (macOS Bonus)#

If you’re on macOS and using iTerm2, there’s a whole other level of tmux experience available. This section is specifically for you. Linux and Windows readers: feel free to skip ahead to the cheat sheet. Everything above works without iTerm2.

What Is tmux Integration?#

iTerm2 has a native tmux integration mode that turns each tmux window into a real iTerm2 tab or window. You get the full macOS native UI: real scrollbars, Cmd+D to split panes, native find (Cmd+F), menu bar items, and the ability to drag tabs around like normal iTerm2 tabs. All while keeping tmux’s session persistence underneath.

You activate it with a simple flag: tmux -CC

tmux -CC new -s hermes-main

Or to create/attach in one shot (my preferred approach):

tmux -CC new -A -s hermes-main

The -A flag says “attach if it exists, create if it doesn’t.” The -CC says “run in iTerm2 integration mode.”

When you run this, iTerm2 opens a small control window with a menu:

** tmux mode started **

Command Menu
----------------------------
esc    Detach cleanly.
  X    Force-quit tmux mode.
  L    Toggle logging.
  C    Run tmux command.

You’ll probably want to auto-hide this. Go to iTerm2 > Settings > General > tmux and check “Automatically bury the tmux client session after connecting.” That control window disappears into the Session > Buried Sessions menu, and you just see your normal iTerm2 windows.

What You Get#

In integration mode, every tmux window becomes a native iTerm2 tab or window. Every pane split becomes a native iTerm2 split pane. This means:

  • Cmd+T opens a new tmux window (appears as a new tab)
  • Cmd+D and Cmd+Shift+D split panes left/right and top/bottom
  • Cmd+[ and Cmd+] navigate between panes
  • Cmd+Shift+Enter makes a pane full screen (like tmux zoom)
  • Native scrollback: your mouse wheel and trackpad gestures just work
  • Native find: Cmd+F opens iTerm2’s find bar, not tmux’s search
  • Menu bar integration: Shell > tmux gives you access to tmux operations from the menu

What You Give Up#

Integration mode isn’t free. The tradeoffs are worth understanding:

  • All tmux windows share the same size. In integration mode, every tmux window must be the same width and height (determined by the smallest attached client). If you have a window that’s 120 columns wide on your main monitor and another on a smaller screen, there will be gray space.
  • It only works locally. tmux -CC is designed for iTerm2. It doesn’t help when you SSH into a remote server: you still use regular tmux there.
  • The muscle memory splits. If you get used to Cmd+D for splitting panes, you’ll reach for it when SSH’d into a server and it won’t work. I use integration mode for local work and native tmux for remote sessions. The native tmux skills from the rest of this article still apply everywhere.

The Setup I Recommend#

For local work, configure iTerm2 to auto-start tmux integration. Create a profile that runs tmux -CC new -A -s main as its command:

  1. Go to iTerm2 > Settings > Profiles
  2. Create a new profile or edit your default
  3. Under General > Command, select “Command” and enter: tmux -CC new -A -s main
  4. Under General > Working Directory, select “Home directory”

Now whenever you open that profile, iTerm2 starts (or attaches to) a tmux session called main. No manual tmux invocation needed.

Also configure these settings:

  • General > tmux > Automatically bury the tmux client session: hides the control window
  • General > tmux > When attaching, restore windows as: choose “Tabs” or “Windows” depending on your preference
  • Appearance > Panes > Show per-pane title bar with split panes: uncheck this for a cleaner look
  • Appearance > Dimming > Dimming affects only text, not background: better inactive pane dimming

For remote work over SSH, use regular tmux (no -CC). The ~/.tmux.conf you built in the earlier sections is what makes that experience great. You get the best of both worlds: a native macOS UI when you’re local, and the universal tmux experience when you’re remote.

The Cheat Sheet#

Here’s the condensed reference in a printable one-page PDF. Print it, stick it on your wall, keep it next to your monitor.

Download the tmux cheat sheet PDF — one page, landscape, ready to print.

Save it, print it, stick it on your wall.

Why tmux Won#

It’s 2026. There are newer, shinier terminal multiplexers with mouse-driven interfaces, floating windows, WebAssembly plugins, and built-in file explorers. I’ve tried most of them.

I keep coming back to tmux because it doesn’t try to be anything other than what it is: a reliable way to keep multiple terminal sessions alive and organized. It works over SSH. It works on a Raspberry Pi. It works in a Docker container. It works on a fresh EC2 instance that has nothing installed except what the base AMI ships with. It doesn’t need a GPU, an Electron runtime, or a configuration format that requires its own dedicated documentation site.

And for the specific problem I had — multiple Hermes Agent instances running in parallel, needing to be visible, manageable, and persistent — tmux is not just the best solution. It’s the only solution that checks every box.

I fell out of practice with it for years. But tmux is the kind of tool that waits for you. It doesn’t change its keybindings between versions. It doesn’t abandon its configuration format for a new one. It just stays there, maintained and stable, ready for when you remember why you needed it.

Hermes brought me back. If you’re running terminal-based AI agents — or honestly, if you’re doing anything serious in the terminal — tmux will bring you back too.

Give it an evening. You’ll wonder why you ever left.