tmux sessions
Living in tmux full-time: Ghostty starts it for you, sessions survive reboots, and how saving actually works. Keybinding reference lives in
tmux.md; this page is the workflow.
Prefix is Ctrl+S throughout, written Prefix.
The five keys that cover almost everything
Prefix d detach — leave the session running, close the terminal
Prefix C-j switch session (fzf picker)
Prefix C-s save a snapshot of every session <- the one you must remember
Prefix R rename the current session
Prefix X kill the current session (asks first)
A day in the life
DAY 1
open ghostty no server, no snapshot
-> "Session name (Enter for 'main'):" you type: work
-> split panes, start nvim
Prefix C-s -> snapshot: [work]
open ghostty "work" is busy
-> "Session name (Enter for 'main'):" you type: notes
-> a different layout
Prefix C-s -> snapshot: [work, notes] supersedes the first snapshot
shut down panes die, the snapshot on disk does not
DAY 2
open ghostty no server, snapshot exists
-> "restoring layout saved 2026-07-24 18:42 (14h ago)..."
-> work (3 panes) and notes (2 panes) rebuilt, cwds and nvim included
-> attaches to whichever you used last
open ghostty "notes" is free -> attaches straight to it, no prompt
Prefix C-j -> fzf between them
status bar -> "saved 14h" in yellow: your layout has drifted, press Prefix C-s
The only habit to build is Prefix C-s before you finish. Everything else is automatic.
Mental model
tmux server ....................... one background process, outlives every terminal window
|
+-- session "work" .............. a workspace; this is what gets saved and restored
| +-- window 1 .............. like a tab
| | +-- pane ............ a shell
| | +-- pane
| +-- window 2
|
+-- session "notes"
The one rule: the server is not your terminal. Closing a Ghostty window kills only the
view. The session, its panes, and everything running in them keep going. That is why
Prefix d and clicking the X are the same thing here, and why nothing is ever lost by
closing a window.
Only two things actually destroy a session: Prefix X, and exiting every pane in it.
What happens when you open a Ghostty window
~/.local/bin/tmux-attach decides, in this order:
already inside tmux ................... plain shell, no nesting (matters over ssh)
TMUX_AUTOSTART=0 ...................... plain shell
no server running + snapshot exists ... restore everything, then attach
a session with no window attached ..... attach to the most recently active one
otherwise ............................. ask for a name, create it
Why “no window attached” and not just “any session”: two windows attached to one session mirror each other keystroke for keystroke and both shrink to the smaller one’s size. So each window gets its own session, and a session you closed is reused rather than piling up.
The name prompt
Session name (Enter for 'main-2'):
Enter (empty) ............. uses the offered name: main, main-2, main-3, ...
a name that exists, free .. attaches to it — typing a name is also how you jump to it
a name that exists, busy .. says so and asks again
anything else ............. creates it
Ctrl+D .................... plain shell, no tmux
. and : are replaced with - (tmux won’t accept them in a session name).
Names are worth typing: they are what restore brings sessions back as. main-2 tells
you nothing tomorrow morning. Renamed later with Prefix R — the new name is picked up by
the next Prefix C-s.
Saving and restoring, honestly
This is tmux-resurrect, and it does not work the way you would guess.
A save is a snapshot of the whole server
Prefix C-s writes every session at once into one file. There is no per-session save.
Two consequences:
- Saves are not additive. Kill
notes, then pressPrefix C-s, andnotesis gone from the new snapshot. The snapshot always describes exactly what was running when you pressed the key. - You never save “just this session”. Saving from inside
workalso capturesnotes.
Where it lives
~/.local/share/tmux/resurrect/
last -> tmux_resurrect_20260724T184200.txt symlink to the newest
tmux_resurrect_20260724T184200.txt
tmux_resurrect_20260723T091500.txt older snapshots are kept
Prefix C-r (and the automatic restore on a cold start) always reads last. Old snapshots
are pruned after 30 days.
Rolling back to an earlier snapshot — repoint last and restore:
cd ~/.local/share/tmux/resurrect
ls -t # newest first
ln -sf tmux_resurrect_20260723T091500.txt last
Then Prefix C-r. Nothing is overwritten until your next Prefix C-s.
What survives and what does not
layout, splits, sizes ......... yes
window and session names ...... yes
working directory per pane .... yes
nvim, less, man, top, htop .... yes restarted from an allowlist
any other program .............. no comes back as a plain shell
pane scrollback ................ no deliberately off here
shell variables, background jobs no
The allowlist is @resurrect-default-processes:
vi vim view nvim emacs man less more tail top htop irssi weechat mutt.
Concretely: a snapshot holding nvim report.typ and typst watch report.typ restores the
nvim pane running nvim, and the typst pane as a bare shell in the right directory. To have
typst watch restart too, add to tmux.conf:
set -g @resurrect-processes 'typst'
The staleness trap
Restore is automatic; saving is not. So this can happen:
day 2 restore yesterday's snapshot, work all day, forget Prefix C-s
day 3 restore ... yesterday's snapshot again — the same one
day 4 still that same snapshot
Nothing is broken, and nothing warns you. That is what the status-bar segment is for:
saved 12m grey fresh, ignore it
saved 5h yellow drifted today, worth a Prefix C-s
saved 7mo red this is what tomorrow morning would restore
never saved red no snapshot at all
It reads the mtime of last, so it turns grey within five seconds of a save.
Is history shared between sessions?
Two different histories, two different answers.
Shell history — yes, completely shared, and always has been. .zshrc sets
share_history and inc_append_history against a single HISTFILE
($XDG_CACHE_HOME/zsh_history). A command run in one pane is immediately available to
Ctrl+R in every other pane, every window, every session — and it outlives reboots. This
is zsh, not tmux; sessions have no effect on it either way.
Scrollback — no. Each pane has its own buffer (50 000 lines, from tmux-sensible). It is never shared between panes and is not saved across reboots. Restored panes start blank.
Detach vs close vs kill
action keys session lives on? panes keep running?
detach Prefix d yes yes
close the ghostty win window close yes yes
kill the session Prefix X no no
exit every pane exit / Ctrl+D no no
The first two are identical in effect. Use whichever is nearer to hand.
Session cheat-sheet
From inside tmux:
Prefix C-j switch session (fzf)
Prefix s switch session (tmux's own list, shows windows as a tree)
Prefix C-n create a session by name, in a popup
Prefix R rename this session
Prefix X kill this session
Prefix d detach
From any shell:
tmux ls # list sessions
tmux attach -t '=work' # attach to one by name
tmux new-session -s notes # create one
tmux kill-session -t '=notes' # kill one
tmux kill-server # kill everything (the snapshot on disk survives)
Two quoting traps worth knowing
Always write '=name', quoted. The = tells tmux to match the name exactly; without
it -t work also matches workshop, and tmux picks one for you. And the quotes matter in
zsh specifically — a bare word starting with = is a command-path expansion:
tmux kill-session -t =notes # zsh: notes not found
tmux kill-session -t '=notes' # correct
Getting out of tmux
TMUX_AUTOSTART=0 ghostty # one window with a plain shell
ghostty -e zsh # same thing via ghostty's own flag
Ctrl+D at the name prompt also drops you into a plain shell for that window. Inside an
existing tmux session (over ssh, say) tmux-attach is a no-op and starts a plain shell, so
sessions never nest by accident.
To stop the whole thing permanently, remove the command = line from
~/.config/ghostty/config.
Troubleshooting
Ghostty opens and closes instantly
tmux-attach is missing from PATH -> run `stow -v .` in ~/Dotfiles.
To get a terminal meanwhile: `ghostty -e zsh`, or a TTY with Ctrl+Alt+F2.
The same old layout gets restored every morning
You are not saving. Check the status bar colour; press Prefix C-s before you finish.
I am in a session called "0"
A snapshot taken before this setup existed, from a plain `tmux` with no -s.
Prefix R to rename it, then Prefix C-s so the name sticks.
Two windows showing the same panes
Two clients on one session. Prefix d in one, then reopen — it will pick a free
session or offer to make one.
Sessions piling up
`tmux ls` to see them, Prefix X to kill the one you are in. Remember the next
Prefix C-s is what removes them from the snapshot too.
A restored pane is a plain shell instead of my program
Not on the resurrect allowlist. See "What survives and what does not".
Config edits are not taking effect
tmux.conf: Prefix r. ghostty: reloads on save, restart the window if not.
Learning path
Week 1 — stop losing work. Only three keys: Prefix d to leave, Prefix C-j to move
between sessions, and a name at the prompt that means something. Close windows freely and
notice that nothing dies.
Week 2 — make it persist. Prefix C-s before you shut down; watch the status segment
go grey. Reboot, and see the layout come back. Once that is habit, learn the rollback so a
bad save is never final.
See also: tmux.md (all keybindings), ghostty.md (terminal config).