A practical guide to making tmux sessions survive reboots and reviving dead panes, in three layers. It goes beyond the usual tmux-resurrect / tmux-continuum setup to cover a real production incident where every restored session died seconds after boot — including the root cause and the fix.
A working .tmux.conf and a respawn-pane.sh helper are included.
The longer you use tmux, the more you run into these:
- Rebooting wipes every open session. You have to rebuild your window layout and per-pane working directories from scratch.
- When a process in a pane dies, the pane disappears with it. You can't inspect the last error output, and you can't relaunch it in the same spot.
These are different problems with different solutions, so this guide splits them into three layers:
| Layer | What it solves | Mechanism |
|---|---|---|
| Stage 1 | Restore entire sessions across a reboot | tmux-resurrect + tmux-continuum |
| Stage 2 | Keep a pane and respawn it in place when its process dies | remain-on-exit + respawn-pane |
| Stage 3 | Avoid the "all sessions die on restore" trap | @resurrect-capture-pane-contents 'off' |
tmux-resurrect saves and restores the session tree (windows, panes, layout, and each pane's working directory), and tmux-continuum automates it.
# Plugins (managed by TPM)
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @resurrect-dir "$HOME/.local/share/tmux/resurrect"
# Auto-save every 15 min, auto-restore on tmux start, and restore on boot.
set -g @continuum-save-interval '15'
set -g @continuum-restore 'on'
set -g @continuum-boot 'on'@continuum-save-interval is the periodic-save interval. On its own, it can lose work in cases like "reboot right after opening a new window." Adding hooks that save the moment the topology (sessions / windows / panes) changes closes that gap.
set-hook -g after-new-session 'run-shell -b "~/.tmux/plugins/tmux-resurrect/scripts/save.sh quiet"'
set-hook -g after-new-window 'run-shell -b "~/.tmux/plugins/tmux-resurrect/scripts/save.sh quiet"'
set-hook -g after-split-window 'run-shell -b "~/.tmux/plugins/tmux-resurrect/scripts/save.sh quiet"'
set-hook -g session-closed 'run-shell -b "~/.tmux/plugins/tmux-resurrect/scripts/save.sh quiet"'resurrect exposes hooks before and after a restore. You can use them to, for example, rebuild panes that were running a specific command with your own logic — e.g. deterministically relaunching a process from your own source of truth when resurrect's built-in restore is unreliable for it.
set -g @resurrect-hook-post-save-layout '~/.tmux/scripts/your-post-save.sh'
set -g @resurrect-hook-post-restore-all '~/.tmux/scripts/your-post-restore.sh'Stage 1 was about surviving a reboot. Stage 2 is about a process dying while tmux is still running. By default, when a process exits, the pane goes with it. Enabling remain-on-exit keeps the pane as a Dead marker, so you can inspect the last output and bring it back in the same spot.
# When a process exits, mark the pane "Dead" instead of destroying it.
set -g remain-on-exit on
# Respawn the focused dead pane in place (-k kills the existing one first).
bind R respawn-pane -kPress prefix + R to respawn the focused pane in place. For a whole window, use respawn-window.
Tradeoff: Setting
remain-on-exit onglobally also keeps normal shell exits around asDeadpanes. If that bothers you, don't set it globally — enable it per window withset-window-option remain-on-exit on, or use the bundledscripts/respawn-pane.shto revive panes only when you need to.
To respawn several dead panes at once, use the bundled helper:
scripts/respawn-pane.sh # respawn every dead pane in the current session
scripts/respawn-pane.sh %12 # respawn one pane by pane_idThis is the most important lesson in the guide. Do not set @resurrect-capture-pane-contents to 'on'. In some environments it makes every restored session die within seconds of a reboot.
After one reboot, continuum correctly restored 13 sessions. But every restored pane came up with an empty pane_current_command, and all of the sessions died within seconds.
With @resurrect-capture-pane-contents 'on', resurrect's restore.sh rebuilds each pane like this:
cat '<saved pane contents>'; exec $(tmux_default_command)If tmux_default_command resolves to empty in your environment, exec runs with no target, so the pane's command string simply completes. A pane whose command has completed exits, and once a window runs out of panes, the window — and then the session — dies with it. That chain reaction is what "everything dies right after restore" actually is.
Set it to 'off'. With 'off', restore.sh creates panes with new-session -c <dir> (no command), so tmux's own default shell starts and panes survive exactly like a normal new-session.
set -g @resurrect-capture-pane-contents 'off'You lose restoration of each pane's on-screen contents (scrollback), but that is far better than losing every session. Window layout, pane structure, and working directories are still restored with
'off'.
A working minimal setup is included in .tmux.conf. The three takeaways are:
- resurrect + continuum to auto-restore sessions across a reboot (Stage 1).
remain-on-exit+respawn-paneto keep dead panes and revive them in place (Stage 2).- Always keep
@resurrect-capture-pane-contents 'off'to avoid the post-restore wipeout (Stage 3).
- tmux 3.x
- Plugins managed by TPM (the tmux Plugin Manager)
- Verified on Linux. macOS should behave similarly, but Stage 3 depends on how
tmux_default_commandresolves in your environment, so verify there before relying on it.