Mosh patch series

Mosh changes for bandwidth-constrained links.

This branch changes how Mosh compresses terminal state, schedules competing traffic, and moves bulk data. It is aimed at satellite, radio, metered, and other links where bandwidth is scarce and interactive traffic still needs to arrive first.

Snapshot
c03cd19
Focus
wire use + scheduling
Status
patch series

01 / Artifacts

What changed, in the source.

Each entry starts with the implementation artifact, then states the reason for the change and the practical effect it is intended to have.

A01

Negotiated zstd-22 state compression

Changed

Once both peers advertise zstd, every serialized state update uses zstd level 22. Initial packets stay with zlib for negotiation.

Why

Screen updates are small but frequent, and satellite bandwidth is expensive. State compression is a core part of the link strategy.

Why it matters

There is no size threshold, zlib comparison, or codec-level tuning. After negotiation, the state codec is always zstd-22.

A02

Session-specific state dictionaries

Changed

State updates can be sampled, compiled into a zstd dictionary, and supplied during session setup.

Why

Terminal applications repeat structures, prompts, status lines, and escape sequences that a trained dictionary can represent compactly.

Why it matters

Dictionary compression activates only when both peers advertise the same dictionary ID, keeping the choice explicit and verifiable.

A03

Priority-aware stream forwarding

Changed

Forwarded bytes are coalesced and rate-limited in separate medium- and low-priority token buckets.

Why

A tunnel, agent, or X11 client can generate enough queued traffic to compete with terminal state on a narrow uplink.

Why it matters

Terminal traffic stays ahead. Agent and X11 use medium priority; TCP and SOCKS use low priority.

A04

Paced, repairable file transfer

Changed

adam-moshcp moves files through an active session using paced datagrams and forward-error-correction symbols.

Why

Loss recovery and bulk transfer need bounds of their own; an unpaced copy can consume the link needed by the shell.

Why it matters

Bulk packets are sent only when reliable terminal or stream traffic is not queued. Reed–Solomon is the default; RaptorQ is optional.

A05

More work inside the session

Changed

The branch adds -L, -R, -D, -A, and -X, plus reliable out-of-band OSC 52 clipboard events.

Why

A remote workflow often needs forwarding and clipboard exchange in addition to terminal text.

Why it matters

Those facilities share the Mosh session and its scheduler instead of requiring each workflow to ignore the link budget.

A06

Lossless WebP Kitty state

Changed

Static Kitty RGB, RGBA, and PNG uploads are decoded once and stored as lossless WebP with image and placement deltas.

Why

Raw pixel uploads are large, while terminal placement changes usually need only a few fields and no new pixels.

Why it matters

Unchanged images are not resent. The client converts WebP back to a standard Kitty RGBA upload only when the local terminal needs it.

A07

Client terminal capability handoff

Changed

The authenticated bootstrap carries the client's exact TERM value into the remote login session.

Why

Mosh previously replaced terminal identity with xterm or xterm-256color, hiding a Kitty-capable Ghostty client.

Why it matters

Remote applications can see xterm-ghostty, select Kitty graphics, and confirm support with the protocol query. The matching terminfo entry is still required remotely.

A08

Side-by-side patched binaries

Changed

Programs and manual pages use an adam- prefix, with optional zstd and RaptorQ build detection.

Why

A protocol patch branch needs to coexist with the stock client and server during evaluation.

Why it matters

The patched and upstream installations can remain on the same machine without replacing one another.

02 / Behavior

The scheduler is the point.

Compression reduces the amount of data. Scheduling determines which data gets the scarce send opportunity when several features are active at once.

Traffic Class Send rule
Terminal state + input primary Scheduled before forwarded streams and bulk transfer.
SSH agent + X11 medium Shares a medium-priority token bucket.
TCP + SOCKS low Uses a separate low-priority token bucket.
adam-moshcp idle Sends only when reliable terminal or stream traffic is not queued.

03 / Inspect

Build the exact branch.

The prefixed binaries are intentional: they let this patch set live beside an ordinary Mosh installation.

shell low-bandwidth-mosh
$ git clone --branch low-bandwidth-mosh --single-branch \
    https://github.com/adamdeprince/mosh.git
$ cd mosh
$ ./autogen.sh
$ ./configure --with-zstd
$ make
$ make check

# Run the prefixed client.
$ adam-mosh user@host

04 / Limits

Evaluation notes.

The branch is a working patch series, not an upstream Mosh release.

Both endpoints

Enhanced protocol features require this branch's client and server. Initial compression remains compatible while peers negotiate support.

Sensitive samples

State sample logs contain uncompressed terminal updates and may include commands, output, or other sensitive terminal contents.

Measure the link

Appropriate forwarding rates and transfer redundancy depend on the capacity, loss pattern, and cost of the actual path.