# Mosh - The SSH Replacement You Didn't Know You Needed

*March 6, 2026*
 — by Flaviu Vlaicu

> 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.



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](https://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)

```bash
brew install mosh
```

Mosh installs to `/opt/homebrew/bin/` on Apple Silicon Macs.

### Ubuntu / Debian

```bash
sudo apt install mosh
```

### RHEL / Rocky / AlmaLinux

```bash
sudo dnf install mosh
```

### Arch Linux

```bash
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:**
```bash
firewall-cmd --permanent --add-port=60000-61000/udp
firewall-cmd --reload
```

**Linux — ufw:**
```bash
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:**

```bash
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:

```bash
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:**

```bash
sudo ln -s /opt/homebrew/bin/mosh-server /usr/local/bin/mosh-server
```

**Verify it works:**

```bash
ssh user@192.168.x.x "which mosh-server"
# Expected: /usr/local/bin/mosh-server
```

---

## Connecting

### Basic Connection

```bash
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
```

```bash
mosh myserver
```

### Non-Standard SSH Port

```bash
mosh --ssh="ssh -p 2222" user@hostname
```

### Specify Server Binary Path (macOS workaround)

```bash
mosh --server=/opt/homebrew/bin/mosh-server user@hostname
```

Make it permanent with an alias in `~/.zshrc`:

```bash
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

```bash
who                        # shows mosh-server entries
ps aux | grep mosh-server  # list mosh-server processes
```

### Kill a Stuck Mosh Session

```bash
# 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:

```bash
# 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.


---
*Source: [https://vlaicu.io/posts/mosh/](https://vlaicu.io/posts/mosh/)*
