mosh server
A drop-in replacement for mosh-server 1.4.0. With Term, coding agents look and behave the way they do on a desktop. With any other mosh client, it is simply mosh. On any server, it idles in 2–3 MB of memory.
Drop-in for mosh-server 1.4.0
termosh is a drop-in replacement for mosh-server 1.4.0. Anything that works with mosh works with termosh, with nothing to change on the client.
The same launch command, options and environment variables (port range, timeouts, locale). Any mosh client starts it the way it starts mosh-server.
The same encrypted UDP protocol and handshake, byte for byte, so roaming, prediction and reconnection behave as they always have.
mosh 1.4.0 ships its own end-to-end test suite. termosh passes it with exactly the results of mosh-server itself: 24 pass, plus the 2 tests upstream marks as expected failures.
Written from scratch in Rust, without any of mosh’s code: mosh is GPL v3, which would require Term to publish its source, and Term is not open source. With none of its code inside, mosh’s license places no conditions on Term. Term’s mosh client is the same from-scratch implementation.
Who gets what
termosh speaks the mosh protocol unchanged, so every mosh client can connect to it. The extras are drawn by Term; any other client gets an ordinary mosh session, exactly as if mosh-server were still there.
| Term + termosh | Other client + termosh | Any client + mosh-server | |
|---|---|---|---|
| Survives Wi-Fi ↔ mobile, sleep and a weak signal | |||
| Memory, one idle session | 2.2 MB | 2.2 MB | 3.8 MB |
| Coding agents follow your light / dark switch | as mosh | — | |
| Whole-frame redraws, no half-drawn replies | as mosh | — | |
| Links you can tap | as mosh | — | |
| Curly, dotted, dashed and double underlines | as mosh | — | |
| The cursor shape the program asks for | as mosh | — | |
| Scroll back through output, no tmux needed | as mosh | — | |
| Everything else: instant agent startup, Shift+Enter, rewrap on resize, tmux copy, etc. → | as mosh | — |
“as mosh” means the client shows what it would with mosh-server: nothing breaks, nothing extra.
With Term
Built for the coding agent on the other end of the session.
Switch Term between light and dark mid-session, and Claude Code or Codex repaint to match at once.
The questions an agent asks on startup are answered on the spot, so it never waits and never starts with features off.
Each picture is held until it is complete and sent whole. No flicker, no half-drawn reply.
A link a program prints arrives as a link, and a tap offers to open or copy it.
Curly red under an error, dotted under a hint: every style and colour arrives.
A bar while you type in vim, a block when you move around, as the program asks.
Ordinary mosh keeps no scrollback. With termosh, every line that scrolls past lands in Term’s history — a build log, a long agent reply, or <code>apt upgrade</code> running under its progress bar — so you just scroll up.
Force-quit Term or lose the phone for a while: when the session resumes, the recent output is back in the scrollback, including what the agent printed while you were away.
Install
termosh runs on the server, in place of mosh-server. One command per host, no root, nothing outside your home directory changes.
Windows is in beta. Tested on Windows Server 2025 x64: attach, typing, resize, scrollback, UTF-8 and CJK, and a clean exit. Not yet tested on Windows 10 or 11 desktops, on ARM64, or over a real network through Windows Firewall.
LinuxAny distribution, x86_64 or ARM64. The build is fully static, so Alpine, older enterprise releases and BusyBox systems work too. It is verified against the release checksums and lands in ~/.local/bin.
macOSApple silicon or Intel. The Mac needs Remote Login turned on (System Settings › General › Sharing), since Term starts the server over SSH.
WindowsWindows 10 1809 or later, x64, with OpenSSH Server running and cmd.exe as its default shell (the default). In PowerShell: download, check the hash, unzip into your profile, and let mosh’s UDP ports through Windows Firewall (an elevated PowerShell; a cloud firewall in front of the server needs the same ports).
curl -fsSL https://term.const.net/termosh/install.sh | sh
iwr https://term.const.net/termosh/0.6.1/termosh-0.6.1-windows-x86_64.zip -OutFile termosh.zip (Get-FileHash termosh.zip).Hash # compare with its line in SHA256SUMS Expand-Archive termosh.zip $env:USERPROFILE\termosh -Force New-NetFirewallRule -DisplayName termosh -Direction Inbound -Protocol UDP -LocalPort 60000-61000 -Action Allow
Edit the host. Under Connection choose Mosh, open Mosh options and put the path the installer printed in mosh-server command.
Edit the host. Under Connection choose Mosh, open Mosh options and put the full path of termosh.exe in mosh-server command, as below. Needs Term 26.7.0 or later.
~/.local/bin/termosh%USERPROFILE%\termosh\termosh.exeThat is all. The next session on this host runs on termosh.
That is all. The next session on this Mac runs on termosh.
That is all. The next session on this host runs on termosh, with cmd.exe as its shell.
~/.local/bin/termosh --version # termosh 0.6.1
& $env:USERPROFILE\termosh\termosh.exe --version # termosh 0.6.1
v=0.6.1; a=$(uname -m) # x86_64 or aarch64 curl -fsSLO https://term.const.net/termosh/$v/termosh-$v-linux-$a.gz curl -fsSLO https://term.const.net/termosh/$v/SHA256SUMS sha256sum -c SHA256SUMS --ignore-missing gunzip termosh-$v-linux-$a.gz mkdir -p ~/.local/bin && install -m 755 termosh-$v-linux-$a ~/.local/bin/termosh
v=0.6.1; a=$(uname -m) # arm64 or x86_64 curl -fsSLO https://term.const.net/termosh/$v/termosh-$v-macos-$a.gz curl -fsSLO https://term.const.net/termosh/$v/SHA256SUMS shasum -a 256 -c SHA256SUMS --ignore-missing gunzip termosh-$v-macos-$a.gz mkdir -p ~/.local/bin && install -m 755 termosh-$v-macos-$a ~/.local/bin/termosh
For every mosh client
Because any other client simply gets plain mosh, termosh can safely be the server every mosh client starts. Term picks up the extras, and everything else keeps working as before.
curl -fsSL https://term.const.net/termosh/install.sh | sudo TERMOSH_INSTALL_DIR=/usr/local/bin sh sudo ln -sf /usr/local/bin/termosh /usr/local/bin/mosh-server
/usr/local/bin comes before /usr/bin on the PATH of almost every distribution, so mosh finds termosh first. To undo it: sudo rm /usr/local/bin/mosh-server.
mosh --server=~/.local/bin/termosh you@your-mac
On a Mac, point the client at it instead of replacing Homebrew’s mosh-server. Every mosh client has a server option like this one.
Other mosh clients: point their server option at termosh.exe. On a Windows host they may wait for the whole session before their SSH command returns, until a fix in termosh lands; Term does not wait.
Memory
Measured side by side on the same Linux server, one session each at 80×24.
Idle, termosh needs a little over half of mosh-server’s memory: it is one self-contained program and loads none of the shared libraries mosh-server needs. Scrollback is what costs. termosh keeps the newest ~1,000 lines, a full row each, so after heavy output it uses more than mosh-server — about 5 MB at 80 columns, around 9 MB at 160 — and no more however long the session runs. Start it as TERMOSH_SCROLLBACK=0 termosh and it stays near 2 MB. On macOS, a session uses about 3 MB idle and 8–9 MB after very heavy output, comparable to stock mosh-server’s 8–10 MB; read Activity Monitor’s Memory column, not ps RSS, as macOS keeps some freed memory resident until it needs it.
Network
Measured against stock mosh-server under seven simulated networks, both talking to Term’s own mosh client. Lower is better.
How long a keystroke takes to appear, in milliseconds.
| Network | mosh-server | termosh |
|---|---|---|
| Same machine room · ≈0 ms | 10.5 | 1.0 |
| Home or office network · 10 ms | 23.2 | 13.2 |
| Fast broadband · 30 ms | 44.9 | 35.0 |
| Mobile data · 100 ms | 115 | 107 |
| Weak signal · 100 ms, 5% loss | 114 | 104 |
| Slow link · 150 ms, 1 Mbit/s | 241 | 156 |
| Across the world · 300 ms | 317 | 305 |
How long 5,000 lines of output take to finish on screen, in milliseconds.
| Network | mosh-server | termosh |
|---|---|---|
| Same machine room · ≈0 ms | 31 | 26 |
| Home or office network · 10 ms | 43 | 36 |
| Fast broadband · 30 ms | 251 | 81 |
| Mobile data · 100 ms | 383 | 224 |
| Weak signal · 100 ms, 5% loss | 136 | 213 |
| Slow link · 150 ms, 1 Mbit/s | 518 | 324 |
| Across the world · 300 ms | 889 | 462 |
Packets sent to a phone that has gone quiet, over 20 seconds while output keeps running — less data and less battery.
| Network | mosh-server | termosh |
|---|---|---|
| Same machine room · ≈0 ms | 925 | 6 |
| Home or office network · 10 ms | 893 | 6 |
| Fast broadband · 30 ms | 908 | 6 |
| Mobile data · 100 ms | 376 | 6 |
| Weak signal · 100 ms, 5% loss | 376 | 7 |
| Slow link · 150 ms, 1 Mbit/s | 248 | 6 |
| Across the world · 300 ms | 131 | 6 |
How long the screen takes to catch up when the phone comes back, in milliseconds.
| Network | mosh-server | termosh |
|---|---|---|
| Same machine room · ≈0 ms | 946 | 22 |
| Home or office network · 10 ms | 951 | 33 |
| Fast broadband · 30 ms | 984 | 58 |
| Mobile data · 100 ms | 1,031 | 126 |
| Weak signal · 100 ms, 5% loss | 1,031 | 126 |
| Slow link · 150 ms, 1 Mbit/s | 1,063 | 182 |
| Across the world · 300 ms | 1,232 | 327 |
These results need termosh 0.5.6 and Term 26.7.2 or later — the app’s own mosh client is part of the improvement. termosh 0.5.6 against mosh-server 1.4.0, three runs per cell, medians. Networks are simulated (Linux netem) on one machine, so real links add their own variation. One case where stock does better: a burst of output on a weak mobile signal.
Downloads · v0.6.1
Static, stripped binaries, gzipped (Windows: a zip). On Linux and macOS the installer picks the right one for you.
| Platform | File | Size |
|---|---|---|
| Linux · x86_64 | termosh-0.6.1-linux-x86_64.gz sha256 864f6ce75c0ed80f… · 0.87 MB | 0.87 MB |
| Linux · aarch64 | termosh-0.6.1-linux-aarch64.gz sha256 2a417feb0795f6e7… · 0.81 MB | 0.81 MB |
| macOS · arm64 | termosh-0.6.1-macos-arm64.gz sha256 e75b57fb7170f50a… · 0.71 MB | 0.71 MB |
| macOS · x86_64 | termosh-0.6.1-macos-x86_64.gz sha256 282011c959d13a18… · 0.75 MB | 0.75 MB |
| Windows (beta) · x86_64 | termosh-0.6.1-windows-x86_64.zip sha256 fd08203ef73c108a… · 0.77 MB | 0.77 MB |
0.6.1: long sessions full of links no longer stall typing for seconds, emoji keep the right width however long a session runs, and heavy output costs the server less CPU.
showing or hiding the keyboard no longer repeats lines in Term’s history, apt’s output now reaches your scrollback, and an image cut off part-way (Ctrl+C during icat) no longer leaves the screen blank.
typing echoes about twice as fast in Term, now as quick as stock mosh or quicker; no more one-second stalls on fast links, and steady output sends far fewer packets.
coding agents’ status reports are read the way Ghostty reads them, so one sub-task clearing its status no longer wipes the others.
Windows (beta): the server steps into the background once connected, as on Linux and macOS.
Windows: the session ends when its shell exits.
about half the memory on macOS after heavy output.
every line of a sudden burst of output (seq 1 200) now reaches your scrollback.
scrollback over mosh: output that scrolls past lands in Term’s history, and recent output comes back when you reattach.
sha256sum -c SHA256SUMS --ignore-missing # macOS: shasum -a 256 -c … · Windows: Get-FileHash
Good to know
termosh uses the same UDP ports as mosh, 60000–61000. A firewall that lets mosh through lets termosh through.
Mosh is part of Term Pro from 26.6.3, and termosh comes with it. The extras need Term 26.7.0 or later.
To give you scrollback, termosh keeps the newest ~1,000 lines of output in RAM — never on disk — and a program’s clear-scrollback wipes it. About 3 MB per session at 80 columns, and the first screen after you attach is a larger update. Start it as TERMOSH_SCROLLBACK=0 termosh to turn it off.
Delete ~/.local/bin/termosh and clear the host’s mosh-server command. The next session is back on mosh-server.
On a 300 ms link a keystroke still takes about 300 ms; no server changes that. termosh removes the waiting mosh adds on top, and the data sent to a phone that is asleep.
No utmp/wtmp entry, so who and last do not list termosh sessions; no colour-count emulation for -c (it is accepted and sets TERM, as stock); no verbose logging for -v (set TERMOSH_DEBUG for wire tracing instead). Everything else behaves as mosh-server.