If you’ve ever had an SSH session freeze mid-command because you switched from Wi-Fi to mobile, or lost your work because a hotel network dropped for three seconds, Mosh is the tool that fixes all of that.
What is Mosh?
Mosh (Mobile Shell) is a remote terminal application that replaces SSH for interactive sessions. It uses SSH only for the initial authentication handshake, then hands off to its own UDP-based protocol (SSP β State Synchronization Protocol) for the actual terminal session.
It was developed at MIT and is open source, available at mosh.org.
Why Mosh Over SSH?
Roaming Without Reconnecting
This is the killer feature. When your IP address changes β switching from office Wi-Fi to a mobile hotspot, closing your laptop lid, or just having a flaky connection β Mosh automatically reconnects your session. No dropped shell, no lost context, no broken pipe.
SSH maintains a TCP connection that dies the moment the network path changes. Mosh uses UDP and tracks state on both ends, so it survives anything short of the server itself going down.
Local Echo β Snappy Even on High Latency
Mosh predicts what you’re typing and renders it locally before the server confirms it. On a high-latency link (VPN, satellite, mobile data), SSH feels sluggish because every character waits for a round-trip. Mosh feels instantaneous. Characters that haven’t been confirmed by the server are shown underlined, so you always know the sync state.
Clean Disconnect and Resume
If your connection drops completely, Mosh shows [mosh] waiting for network... and resumes exactly where you were when connectivity returns. No need to reconnect manually.
No More Zombie Sessions
With SSH, a dropped connection often leaves a zombie shell on the server waiting for TCP timeout. Mosh handles disconnects cleanly β the server-side process waits for you to return rather than hanging indefinitely.
Installation
macOS (Homebrew)
brew install mosh
Mosh installs to /opt/homebrew/bin/ on Apple Silicon Macs.
Ubuntu / Debian
sudo apt install mosh
RHEL / Rocky / AlmaLinux
sudo dnf install mosh
Arch Linux
sudo pacman -S mosh
Setup
On the Server
Mosh requires SSH access to already work. Beyond that, you need to open UDP ports 60000β61000 on the server firewall β Mosh uses one port per session from this range.
Linux β firewalld:
firewall-cmd --permanent --add-port=60000-61000/udp
firewall-cmd --reload
Linux β ufw:
ufw allow 60000:61000/udp
On Linux, mosh-server installs to /usr/bin/ and is in PATH automatically. No further configuration needed.
macOS Server β Extra Steps Required
macOS with Homebrew has a PATH issue: SSH non-interactive sessions don’t load your shell profile, so mosh-server in /opt/homebrew/bin/ is invisible when the client tries to launch it.
Step 1 β Enable Remote Login on the server Mac:
sudo systemsetup -setremotelogin on
Or via System Settings β General β Sharing β Remote Login.
Step 2 β Fix the PATH for SSH sessions:
On the server Mac, add Homebrew to the path loaded by non-interactive shells:
echo 'export PATH="/usr/local/bin:/opt/homebrew/bin:$PATH"' >> ~/.zshenv
Note: use ~/.zshenv, not ~/.zshrc. Only .zshenv is loaded in non-interactive SSH sessions.
Step 3 β Create a symlink as a fallback:
sudo ln -s /opt/homebrew/bin/mosh-server /usr/local/bin/mosh-server
Verify it works:
ssh [email protected] "which mosh-server"
# Expected: /usr/local/bin/mosh-server
Connecting
Basic Connection
mosh user@hostname
Mosh piggybacks on SSH for auth, so your existing ~/.ssh/config entries work:
Host myserver
HostName 192.168.1.100
User flaviu
IdentityFile ~/.ssh/id_ed25519
mosh myserver
Non-Standard SSH Port
mosh --ssh="ssh -p 2222" user@hostname
Specify Server Binary Path (macOS workaround)
mosh --server=/opt/homebrew/bin/mosh-server user@hostname
Make it permanent with an alias in ~/.zshrc:
alias mosh='mosh --server=/opt/homebrew/bin/mosh-server'
Useful Commands & Flags
| Command / Flag | Purpose |
|---|---|
mosh user@host | Basic connection |
mosh --ssh="ssh -p 2222" user@host | Custom SSH port |
mosh --server=/path/to/mosh-server user@host | Explicit server binary path |
mosh --predict=always user@host | Aggressive local echo (snappier feel) |
mosh --predict=never user@host | Disable local echo (low-latency links) |
mosh --predict=experimental user@host | Predict even newlines |
mosh --port=60001 user@host | Use a specific UDP port |
mosh --no-init user@host | Don’t clear the screen on connect |
mosh --ssh="ssh -A" user@host | Forward SSH agent |
mosh user@host -- tmux new-session -A -s main | Connect directly into tmux session |
Check Active Mosh Sessions on Server
who # shows mosh-server entries
ps aux | grep mosh-server # list mosh-server processes
Kill a Stuck Mosh Session
# Find the PID
ps aux | grep mosh-server
# Kill it
kill <PID>
Mosh + Tmux: The Ideal Combo
Mosh handles connectivity β roaming, reconnection, latency. Tmux handles session persistence β windows, panes, detach/reattach.
Together they give you a terminal session that survives anything:
# Connect and attach to (or create) a persistent tmux session
mosh user@host -- tmux new-session -A -s main
The -A flag tells tmux to attach to main if it exists, or create it if it doesn’t. Every connection lands in the same session regardless of how many times you’ve disconnected.
Limitations Worth Knowing
- Requires UDP β environments that block all UDP (some corporate firewalls, strict VPNs) will prevent Mosh from working. Fall back to SSH in those cases.
- No session resumption after server reboot β Mosh survives network drops but not a server restart.
- Scrollback works differently β Mosh manages the terminal state itself, so scrollback in your terminal emulator may not work as expected. Use tmux scrollback instead (
Ctrl+b [to enter scroll mode). - No X11 forwarding β Mosh doesn’t support X11 forwarding. Use SSH directly if you need it.
Summary
Mosh is a straightforward upgrade over plain SSH for any situation where your network isn’t perfectly stable β which is most situations outside of a wired data centre connection. Install it on both ends, open UDP 60000β61000, and you get a terminal that just stays connected no matter what your network does.
On macOS specifically, the one extra step is fixing the PATH in ~/.zshenv on the server side so that non-interactive SSH sessions can find mosh-server. Once that’s done, it’s as seamless as on Linux.