Guides · September 2026

mosh vs SSH

Two answers to “how do I keep a shell on a machine that isn’t here” — the mechanics that separate them, what each gives up, and what has arrived since.

SSH is a stream; mosh is a state.

SSH is an encrypted byte stream over one TCP connection: keystrokes go up it, the terminal’s output comes down it, and the connection is the session. When TCP dies — the laptop sleeps, the address changes from Wi-Fi to cellular, the train enters a tunnel — the session dies with it and the shell on the far end gets a hangup. ServerAliveInterval and ServerAliveCountMax in ssh_config decide how quickly the client notices; they don’t change the outcome. tmux or screen on the server keeps the process alive, but that is a second tool doing a job SSH doesn’t.

mosh keeps SSH for exactly one thing. The mosh command logs in over SSH, starts mosh-server as you, and the server “listens on a high UDP port and sends its port number and an AES-128 secret key back to the client over SSH.” Then SSH exits. From there client and server run the State Synchronization Protocol over UDP: instead of a stream of bytes, each side holds a picture of the terminal screen and they synchronise the difference, in datagrams encrypted with AES-128 in OCB mode, with a heartbeat at least every three seconds. Roaming falls out of the design — “every time the server receives an authentic packet from the client with a sequence number higher than any it has previously received, the IP source address of that packet becomes the server’s new target” — so sleeping the laptop, switching networks, and losing the link for an hour all resume without a reconnect.

The other half of mosh’s reputation is predictive local echo: the client models what the server will do with your keystrokes and shows the result before the round trip completes; on a bad link, “outstanding predictions are underlined so you won’t be misled.” --predict=adaptive is the default, always and never the alternatives, and Ctrl-^ . ends a session by force.

What mosh gives up.

The design that survives roaming is also the design that can’t carry the rest of SSH.

Scrollback

“Mosh synchronizes only the visible state of the terminal.” Output that scrolled off the screen while you were disconnected is gone from the client; the project’s own advice is to run tmux or screen on the remote side for history.

Forwarding of every kind

Per the README, “Mosh does not support X forwarding or the non-interactive uses of SSH, including port forwarding.” Agent forwarding was requested in issue #120 and implemented in a pull request that was never merged. The SSH connection that started the session is closed, so nothing that rides an SSH connection can ride mosh.

Non-interactive use

scp, sftp, rsync and git over ssh are SSH the transport, not SSH the shell, and mosh has no equivalent. In practice you keep both.

The client itself

mosh survives the network changing, not the client disappearing. The session key lives in the client process; if the terminal app is killed — a phone reclaiming memory, a crash — there is no reconnecting to that mosh-server, only starting another.

The firewall reality.

SSH needs one inbound TCP port, 22 by default. mosh needs that port for the login plus inbound UDP: “Mosh will use the first available UDP port, starting at 60001 and stopping at 60999”, and if you forward TCP 22 through a NAT you have to forward the UDP range too. mosh -p 60010 host pins the port; mosh --ssh="ssh -p 2222" host handles a non-standard SSH port. The symptom when UDP is blocked is precise — “Nothing received from the server on UDP port 60003” — meaning SSH worked and the datagrams aren’t getting through.

Both, then, need something listening on the host and a path in from outside: a public address, a port forward, or a VPN. Behind CGNAT or a sealed firewall, neither works without a third tool.

Row by row.

SSHmosh
TransportOne TCP connectionUDP datagrams, state synchronisation
Survives an IP change or sleepNo — the session endsYes — any authentic packet retargets the server
Survives the client dyingNoNo — the key lives in the client
Feel on a bad linkEvery keystroke waits for the round tripPredictive echo, underlined until confirmed
ScrollbackYour terminal’s, completeVisible screen only; tmux for history
Port, agent, and X11 forwardingYesNo
scp, sftp, rsync, gitYesNo — keep ssh for these
Inbound requirementTCP 22TCP 22 plus UDP 60000–61000
EncryptionSSH transportAES-128 OCB per datagram; SSH for login
Phone clientsEvery SSH appBlink and Termius speak it
Release cadenceContinuous, OpenSSH1.4.0 in 2022, five years after 1.3

What has arrived since.

mosh is from 2012 and the question it answered has three newer answers.

Eternal Terminal

ET reconnects automatically like mosh but over TCP, on port 2022 by default, with SSH for the handshake. It keeps native scrolling, supports tmux’s control mode (tmux -CC), and tunnels ports with -t. It is what you want if mosh’s scrollback rule is the thing you can’t live with — and it still needs an open port.

tmux over SSH, with autossh

The old pattern, automated: autossh -M 0 -o ServerAliveInterval=15 -o ServerAliveCountMax=3 -t host 'tmux new -A -s main'. autossh restarts ssh whenever it exits, the keepalives make it exit promptly, and tmux new -A reattaches to the same session every time. The connection is rebuilt rather than resumed, but the session and its scrollback are on the host regardless.

The browser console

The session lives on the host and any browser attaches to it — from self-hosted web terminals to spawnd. The connection becomes disposable because nothing is stored in it; scrollback is wherever the session is.

Surviving the client, not just the network.

Put the two lists together and the gap is visible: SSH loses the session when the connection goes; mosh keeps the connection but loses scrollback and dies with the client; both need a port. What is left wanting is a session that lives on the host on purpose, with its history, reachable from whatever is in your hand, through a firewall that opens nothing.

That is the shape spawnd takes. One daemon per host you own, and it dials out — nothing listens, no UDP range, no VPN. A worker process on the host owns each session’s PTY, so a session survives the closed tab, the dropped connection, the laptop lid, and a daemon restart, scrollback intact. Any browser is the terminal; on a phone it installs to the home screen as a web app, with no keys on the device. Your browser talks to each daemon peer-to-peer, end-to-end encrypted, and the server that introduces them never sees session content. It has no predictive echo — on a truly bad link mosh still feels smoother, and on that link the older tool is the right one.

Start

Keep the session, drop the port.

$curl -fsSL https://spawnd.dev/install.sh | sh
Sign up free
Install the daemon

Questions

Is mosh more secure than SSH?
It authenticates with SSH, so login is exactly as secure as your SSH setup, and its datagrams are encrypted with AES-128 OCB. The 1.4.0 announcement noted no reported vulnerabilities in the preceding decade. It is a different design, not a weaker one — but a smaller, slower-moving one.
Should I run tmux inside mosh?
Yes, if you want scrollback or a session that outlives the client. mosh keeps the connection alive; tmux keeps the process and the history alive. The project itself recommends the pairing.
Does mosh work from an iPhone?
Blink Shell is built around it and Termius supports it. Both are real fixes for a phone that changes networks all day; both still need the host reachable on SSH and the UDP range, and neither gives you scrollback mosh doesn’t have.