tmux: Panes, Windows and Sessions

tmux runs several terminals inside one window, split into panes and windows, and keeps them in a session that goes on running when you detach, close the window or lose the connection to a server, so you can attach again and carry on.

Journeyman · Unix · Linux · Updated

After this lesson you can

  • Split a tmux window into panes and windows, and move between them with Ctrl+B and a key
  • Detach from a tmux session and attach to it again, so work keeps running after the window closes
  • Build a tmux layout from a script with tmux new -d, split-window and attach

Key takeaways

  • tmux new -s NAME starts a session. Ctrl+B is tmux's prefix key: press it, let go, then press the key for what you want.
  • Ctrl+B % splits a pane side by side, Ctrl+B " one above the other, and Ctrl+B with an arrow key moves between panes. Ctrl+B c opens a new window.
  • Ctrl+B d detaches, and everything in the session keeps running. tmux ls lists the sessions, and tmux attach -t NAME brings one back.
  • A session lives on the computer, not in your window, so a closed window or a dropped ssh connection doesn't stop what runs in it.
  • A script can build a layout: tmux new -d -s NAME COMMAND, tmux split-window -t NAME, then tmux attach -t NAME.

You're working on a website. One terminal runs its server, another is where you type, and a third runs the tests. Soon three windows are piled up, and you keep clicking the wrong one. On a server you've logged in to with ssh, it's worse: you get one terminal, and if the Wi-Fi drops halfway through a long job, the connection closes and the job stops with it. nohup from Background Jobs: &, jobs, fg and bg saves one job, but not your screen. tmux (read "tee-mux") solves both. It's a terminal multiplexer: one window holding many terminals, the way a power strip turns one wall socket into six. Web developers keep a server and its tests side by side in it, and administrators run long jobs on servers inside it.

Start a session

Check that tmux is there:

tmux -V
tmux 3.6

If the shell says command not found, install it:

sudo apt install tmux       # Ubuntu, and Ubuntu in WSL
brew install tmux           # a Mac, with Homebrew

Make the practice folder: a tiny website for Bluebird Bakery, and start-server.sh, which serves it at http://localhost:8000 with Python's built-in web server (Is It the Network? ping, curl -I and Ports). Like most real servers, it takes a few seconds to start:

mkdir -p ~/terminal-practice/bakery-site/site
cd ~/terminal-practice/bakery-site
printf '%s\n' '<h1>Bluebird Bakery</h1>' '<p><a href="menu.html">Our menu</a></p>' > site/index.html
printf '%s\n' '<h1>Menu</h1>' '<p>Sourdough loaf: 7.00</p>' > site/menu.html
printf '%s\n' '#!/usr/bin/env bash' '# start-server.sh: serves the site folder at http://localhost:8000.' '# Like most real servers, it takes a few seconds to get going.' 'sleep 3' 'exec python3 -u -m http.server 8000 --directory site' > start-server.sh
chmod +x start-server.sh

Start a session named bakery, then start the server inside it:

tmux new -s bakery
./start-server.sh
$ ./start-server.sh
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...









[bakery] 0:python3*                                     "laptop" 15:15 09-Nov-26

It looks like a fresh terminal, plus a bar along the bottom: tmux's status line. [bakery] is the session's name. 0:python3* is window 0, named after the program running in it, and * marks the window you're in. On the right are the computer's name and the time. (These screens are 80 columns by 12 rows, with the prompt shortened to $.)

Panes: Ctrl+B, then a key

tmux has to tell its keys apart from the program's keys, so every tmux key starts with the prefix key, Ctrl+B: press Ctrl+B, let go, then press the key, as if you said "tmux, please" first. Ctrl+B then % (percent) splits the window side by side into two panes, each a terminal of its own. Your typing goes into the new pane on the right. Ask the server for the menu from there:

curl -s localhost:8000/menu.html
Serving HTTP on 0.0.0.0 port 8000 (http:│$ curl -s localhost:8000/menu.html
//0.0.0.0:8000/) ...                    │<h1>Menu</h1>
127.0.0.1 - - [09/Nov/2026 15:15:16] "GE│<p>Sourdough loaf: 7.00</p>
T /menu.html HTTP/1.1" 200 -            │$
                                        │
                                        │
                                        │
                                        │
                                        │
                                        │
                                        │
[bakery] 0:bash*                                        "laptop" 15:15 09-Nov-26

The page arrives on the right, and the server's log on the left says it sent /menu.html with status 200. The keys you'll use most:

Keys What they do
Ctrl+B % Split the pane side by side
Ctrl+B " Split the pane one above the other
Ctrl+B and an arrow key Move to the pane in that direction
Ctrl+B z Zoom this pane to fill the window, and back
Ctrl+B c Open a new window: a whole new screen, like a browser tab
Ctrl+B n, Ctrl+B 0 Go to the next window, or to window 0
Ctrl+B d Detach from the session
Ctrl+B ? List every key (q closes the list)

exit closes a pane, as it closes a terminal. With two windows, the status line lists both, such as 0:bash- 1:bash*: * for the one you're in, - for the one before.

Detach, and come back later

Ctrl+B d detaches: tmux disappears and you're back in the terminal you started it from, with one line to say so:

[detached (from session bakery)]

Nothing has stopped: the server is still running, with no window showing it:

tmux ls
curl -sI localhost:8000/ | head -n 1
bakery: 2 windows (created Mon Nov  9 15:15:07 2026)
HTTP/1.0 200 OK

tmux ls (list sessions) shows the session, with (attached) at the end while a window shows it. tmux attach -t bakery (-t for target) brings it back as you left it, with any log lines that arrived meanwhile.

That's the difference from an ordinary terminal: a tmux session lives on the computer, not in the window. Close the terminal window while you're attached, open a new one, and tmux ls still lists bakery. A dropped ssh connection is the same.

The session bakery drawn as a box inside the computer, holding two panes: the server and a terminal. In three steps, a terminal window shows it; the window is closed and the session goes on running inside the computer; a new window runs tmux attach -t bakery and shows it again

On a server, start tmux as soon as you've logged in with ssh (Logging In to Another Computer: ssh), and run long jobs inside it. If the connection drops, log in again and type tmux attach: with one session, you don't need its name.

When you're finished, tmux kill-session -t bakery stops the session and everything in it, the server included.

A layout from a script

Building the same panes by hand every morning gets old, and every tmux key has a command a script can run. tmux new -d makes a session without attaching to it (-d for detached), and a command after the name runs in its first pane instead of a shell. tmux split-window -h -t bakery adds a pane beside it (-h for horizontal; -v puts it below), and it takes a command at the end too. Save this as bakery-layout.sh in the practice folder:

#!/usr/bin/env bash
# bakery-layout.sh: the site's server on the left, a terminal for you on the right.
cd "$(dirname "$0")" || exit 1
if ! tmux has-session -t bakery 2>/dev/null; then
  tmux new -d -s bakery ./start-server.sh
  tmux split-window -h -t bakery
fi
tmux attach -t bakery

tmux has-session -t bakery succeeds only when the session exists, so a second run attaches to the one you have instead of failing with duplicate session: bakery. Run it:

chmod +x bakery-layout.sh
./bakery-layout.sh
Serving HTTP on 0.0.0.0 port 8000 (http:│$
//0.0.0.0:8000/) ...                    │
                                        │
                                        │
                                        │
                                        │
                                        │
                                        │
                                        │
                                        │
                                        │
[bakery] 0:bash*                                        "laptop" 15:17 09-Nov-26

One command now sets up your morning. Ctrl+C in the server's pane stops the server and closes its pane. On a Mac, tmux works the same in zsh.

Check yourself

2 questions to try on the lesson page.

So what

tmux turns one terminal into a workspace that waits for you: several terminals side by side, and a session that keeps running when the window closes or the connection drops.

Key terms

Cheat sheets

Related