Part 10 of a series on the tools I actually run.

I stopped using plain ssh for interactive work a few years ago and I’m not going back.

Not because SSH is bad. It’s one of the best pieces of software ever written and everything here still runs on top of it. But it was designed for a world where you sat at a machine with a wired connection and stayed there, and I don’t work like that. I close the laptop mid-command. I walk from wifi to a hotspot. I connect from California to a small board in Germany over a link that is doing its best.

mosh handles all of that. tmux handles what mosh doesn’t. Together they’ve made remote work feel local in a way I’d stopped expecting.

What mosh actually fixes

Mosh uses SSH to authenticate and then hands the interactive session over to its own UDP protocol. Your keys, your ~/.ssh/config, your host aliases all work unchanged. From the outside it looks like SSH with better manners.

Three things it does that SSH structurally can’t:

It survives your laptop sleeping. Shut the lid, walk to another building, open it. You’re still in the session, at the same prompt, with the same half-typed command. SSH’s TCP connection is long dead by then and you’re reconnecting and trying to remember what you were doing.

It survives changing networks. Move from wifi to a hotspot and your IP changes. That kills a TCP connection by definition. Mosh was built around roaming and simply carries on, because the session identity isn’t tied to the address.

It feels fast on a slow link. This is the one people underestimate until they try it. Mosh does predictive local echo: your keystrokes appear immediately, and it reconciles with the server afterwards. On a high-latency link, SSH makes you wait a round trip to see each character you type. Over a transatlantic connection to a small single-board machine, that’s the difference between working and suffering.

That third one is why I originally installed it. I was administering the radio I built for my parents in Germany, and typing over that link with plain SSH was genuinely unpleasant.

Installing it

Both ends need it. It’s not a client-side trick.

brew install mosh           # macOS
sudo apt install mosh       # Debian, Ubuntu

Then connect exactly as you would with SSH:

mosh user@host

The server side needs UDP ports 60000 to 61000 reachable. On a home network behind NAT that means opening them, which is why I mostly don’t bother outside my tailnet. On Tailscale it’s a non-issue, since everything is already reachable.

The locale thing

The single most common mosh failure is a complaint about the locale not being UTF-8, and it stops the connection dead.

It happens because your local terminal is exporting a locale the server doesn’t have generated. On Debian:

sudo dpkg-reconfigure locales

and generate en_US.UTF-8, or whichever you use. This bites almost everyone once, the error message is reasonably clear if you read it, and nobody reads it the first time.

What mosh gives up

Worth being straight about, because it isn’t a drop-in replacement for everything.

No port forwarding. No -L, no -D. When I need a tunnel to reach a web UI on a remote box, that’s plain ssh.

No agent forwarding. If you need your local key available on the remote host, SSH.

Poor scrollback. Mosh only tracks the visible screen, which is what lets it be so efficient over a bad link. Scroll up and there’s much less there than you expect.

Not for scripts. It’s for interactive sessions. Anything automated stays on SSH.

So I keep both. Mosh for sitting in a session and doing things, SSH for everything mechanical.

That scrollback limitation is the obvious lead-in to the other half.

tmux, which is not redundant with mosh

People ask why you’d want both when they both keep sessions alive. They’re keeping different things alive.

Mosh keeps your connection alive across sleeps and network changes. tmux keeps the work alive regardless of whether any connection exists at all. Kill mosh, close the laptop, go away for a day, connect from a completely different machine, reattach, and the long-running job is still there mid-output.

And tmux keeps its own scrollback buffer, which hands back exactly what mosh took away.

The two solve adjacent problems and the combination is better than either.

The way I connect

alias m='mosh $1 -- tmux new -A -s main'

new -A -s main attaches to a session named main if one exists and creates it if it doesn’t. So there’s exactly one session per machine and I always land back in it. No accumulating orphan sessions, no remembering names.

That alias is on every machine, synced along with everything else.

The tmux commands actually worth learning

The prefix is Ctrl-b by default. Press it, let go, then press the next key.

  • Ctrl-b d detach, leaving everything running
  • Ctrl-b c new window
  • Ctrl-b n and Ctrl-b p next and previous window
  • Ctrl-b % split vertically
  • Ctrl-b " split horizontally
  • Ctrl-b o cycle between panes
  • Ctrl-b [ enter copy mode, then arrow keys or PageUp to scroll back, q to leave

That’s genuinely most of it. People write long configs for tmux and you can, but I got most of the value from that list and never needed much more.

One config line I would suggest:

set -g mouse on

in ~/.tmux.conf. Scroll wheel works, clicking a pane selects it, dragging a border resizes it. Purists dislike it. I find it removes a lot of small friction for no real cost.

Why this combination specifically

Because it makes the question “am I connected right now” stop mattering.

Before, a remote session was a thing I had to protect. Don’t close the laptop, don’t walk out of wifi range, don’t start anything long without thinking about what happens if the link drops. That’s a small tax on every remote task, and it shapes what you’re willing to start.

Now the session is just somewhere that exists. I open the laptop and I’m back in it. I switch buildings and I’m still in it. I start something that takes an hour and walk away, and it’s still running when I look again.

The technical description of what mosh and tmux do sounds modest. The change in how it feels to work on remote machines is not modest at all.