●moray: ssh, sftp & terminal

tmux: SSH Sessions That Survive Anything

Your phone locks, the train hits a tunnel, the laptop sleeps — the job keeps running. The five tmux commands worth knowing and how to make them automatic.

Basics · Bartłomiej Żabicki · updated 2026-07-27 · 9 min read

You start a database migration over SSH, switch apps to answer a message, and come back to a dead connection. Did the migration finish? Did it get killed halfway? You genuinely do not know.

tmux makes that question impossible to ask. It moves the shell off your client and onto the server, so the connection becomes a window you look through rather than the thing your work depends on. On a phone, where the operating system suspends your app the moment you leave it, this is not a nicety — it is what makes SSH practical at all.

The idea in one picture

Without tmux, your shell is a child of the SSH session. Kill the connection, kill the shell, kill whatever it was running.

your device ── ssh ──> sshd ──> bash ──> apt upgrade
                          └── connection drops, all of this dies

With tmux, the shell belongs to a tmux server running on the machine. Your SSH session merely attaches to it.

your device ── ssh ──> sshd ──> tmux attach ──┐
                                              ├──> tmux server ──> bash ──> apt upgrade
              connection drops ───────────────┘        (keeps running)

Reconnect, attach again, and you are looking at the same scrollback with the job still going.

The five commands that matter

Install it once:

sudo apt install tmux      # Debian/Ubuntu/Raspberry Pi OS
sudo dnf install tmux      # Fedora/RHEL

Then:

# start or re-enter a session called "work" — the only command you need
tmux new -A -s work

# list what is running
tmux ls

# attach to a specific session
tmux attach -t work

# detach on purpose (leaves everything running)
Ctrl-b then d

# kill a session you are finished with
tmux kill-session -t work

tmux new -A -s work is the one to memorise. -A means attach if it already exists, otherwise create it, so the same command works whether this is your first connection of the day or your fifth. There is no "did I already start it?" branch to think about.

Ctrl-b is the prefix — the key you press before any tmux command. Everything else is a second keystroke after it.

Make it automatic

Typing it every time is one step too many. Put it in your host's run-on-connect command so attaching happens the moment the session opens. In ~/.ssh/config you can approximate this:

Host pi
    HostName 192.168.1.42
    User bart
    RequestTTY yes
    RemoteCommand tmux new -A -s phone

Now ssh pi drops you straight into the persistent session. A client with a run-on-connect field — Moray has one per host — does the same thing without the config gymnastics, and without breaking scp to that host, which RemoteCommand otherwise does.

A terminal session with colored output, a tab bar and a smart bar of modifier keys
A run-on-connect command attaches the session for you, so reconnecting lands you where you left off.

If you go the RemoteCommand route, keep a plain alias for file transfers:

Host pi-scp
    HostName 192.168.1.42
    User bart

The handful of keys worth learning

You can be productive with five. All of them come after Ctrl-b.

KeysWhat it does
dDetach — leave everything running
cNew window (like a tab)
n / pNext / previous window
% / "Split the pane vertically / horizontally
[Enter scroll mode; arrows or PgUp to scroll, q to exit

That last one is the non-obvious one. In tmux you cannot just scroll with a trackpad by default — Ctrl-b [ enters copy mode, and that is where your scrollback lives.

On a phone keyboard, Ctrl is usually a modifier key on the client's accessory bar. If you find Ctrl-b awkward there, remap the prefix to something easier to reach:

# ~/.tmux.conf
set -g prefix C-a
unbind C-b
bind C-a send-prefix

A config worth having

A short ~/.tmux.conf on the server fixes the three things people complain about:

# ~/.tmux.conf

# 1. colours match what your terminal actually supports
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",*256col*:Tc"

# 2. a scrollback worth having
set -g history-limit 50000

# 3. mouse/touch scrolling and pane selection
set -g mouse on

# nicer window numbering
set -g base-index 1
setw -g pane-base-index 1

# tell you at a glance which session you are in
set -g status-left "#[bold] #S "

set -g mouse on is the big one on a touchscreen: it makes scrollback work by dragging, instead of requiring copy mode.

Naming sessions is the whole trick

One session called 0 is barely better than no tmux at all. Name them for the job and they become a to-do list you can walk back into:

tmux new -A -s deploy
tmux new -A -s logs
tmux new -A -s db

tmux ls then tells you what is in flight on that box:

db: 1 windows (created Sat Aug  1 09:12:41 2026)
deploy: 2 windows (created Sat Aug  1 09:40:02 2026)
logs: 1 windows (created Fri Jul 31 22:03:55 2026) (attached)

That output is often the most useful thing you see all morning — it is a record of what past-you left running.

tmux or screen?

screen does the same core job and is sometimes already installed. Prefer tmux for new setups: a readable config format, saner pane handling, scriptable sessions, and ongoing maintenance. If you land on a server that only has screen, the muscle memory translates —screen -R work is roughly tmux new -A -s work, and Ctrl-a d detaches.

What it does not solve

Be clear about the boundary. tmux keeps your shell alive. It does not keep a port-forward alive — a tunnel belongs to the SSH connection itself, so when the connection drops the forward goes with it, tmux or no tmux. That is a client-side problem, solved by reconnecting and restarting the forward (see port forwarding), or by an autossh-style supervisor on a machine that stays awake.

Nor does it protect you from a server reboot: the tmux server is a process, and processes die when the machine does. For work that must survive that, you want systemd units or nohup, not a multiplexer.

The habit

Install tmux on every server you administer. Make tmux new -A -s <you> your run-on-connect command. Turn the mouse on. That is the whole investment, and it converts a dropped connection from a small crisis into a non-event — which is exactly what you need when the only computer you have on you is a phone. See SSH from an iPhone or iPad for the rest of that setup.

Written by Bartłomiej Żabicki

iOS developer writing Swift since 2015, with a homelab he administers from an iPhone more often than he would like to admit. Moray is the SSH client he wanted to exist.

Frequently asked

What is the difference between tmux and screen?
Both keep a shell alive after you disconnect. tmux has a saner configuration format, better split-pane handling, scriptable sessions and active maintenance, which is why it is the usual recommendation today. screen is still fine if it is what is already installed.
How do I get back into a session after my connection drops?
Run tmux attach, or tmux new -A -s <name> which attaches if the session exists and creates it otherwise. That one command works in both cases, so it is the only one worth memorising.
Does tmux use much memory on a small server?
No. The server process is a couple of megabytes plus whatever your shells use. On a Raspberry Pi it is unnoticeable, and it costs far less than re-running an interrupted job.

try it yourself

Moray does all of this natively

A real terminal, dual-pane SFTP, tunnels and jump hosts on iPhone, iPad and Mac. Keys stay in the Keychain, hosts sync over your own iCloud, and there is no account to make.