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 / FlagPurpose
mosh user@hostBasic connection
mosh --ssh="ssh -p 2222" user@hostCustom SSH port
mosh --server=/path/to/mosh-server user@hostExplicit server binary path
mosh --predict=always user@hostAggressive local echo (snappier feel)
mosh --predict=never user@hostDisable local echo (low-latency links)
mosh --predict=experimental user@hostPredict even newlines
mosh --port=60001 user@hostUse a specific UDP port
mosh --no-init user@hostDon’t clear the screen on connect
mosh --ssh="ssh -A" user@hostForward SSH agent
mosh user@host -- tmux new-session -A -s mainConnect 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.