Every few months, someone posts about how painfully slow TRAMP is. And honestly, they’re not wrong – opening a remote file and waiting for that modeline to stop spinning is one of those small frustrations that add up.

So when two new projects showed up promising to fix this, I got curious. tramp-rpc uses a Rust server speaking MessagePack-RPC, flit.el uses a Go server with JSON-RPC. Both claim significant speedups. I decided to actually measure it.

The short answer: with SSH ControlMaster the performance improvments may not be worth it.

The thing nobody talks about: ControlMaster

Here’s what most “TRAMP is slow” discussions miss. Stock TRAMP already uses SSH ControlMaster, which keeps a single persistent connection open and multiplexes all commands through it. Once your first SSH handshake completes (~600ms), every subsequent command reuses that socket with only ~50ms overhead.

So the real question isn’t “SSH vs binary protocol.” It’s: “is 50ms of shell-command overhead per operation enough to justify deploying a server binary on every remote host?”

I ran the benchmarks to find out. The remote host is a Debian 12 box with ~50ms SSH round-trips (a pretty typical setup). I tested read/write with and without cache, and git/magit operations.

Cold cache: the first-access story

These numbers represent the worst case: no cached data, every operation hits the remote.

TestRPCflitsshx
connection-setup614 ms653 ms1.65 s
file-exists16.2 ms15.0 ms45.0 ms
file-attributes14.5 ms14.6 ms37.6 ms
file-read (1KB)16.2 ms0.3 ms42.6 ms
file-read (10MB)74.0 ms808 ms191 ms
file-write (1KB)243 ms16.0 ms246 ms
directory-files46.9 ms15.9 ms43.1 ms
dir-files-and-attrs17.9 ms33.1 ms63.3 ms
process-file (ls)17.4 ms66.7 ms20.9 ms
copy-file129 ms31.1 ms209 ms
multi-stat (10x)155 ms155 ms220 ms

The connection setup improvement is real (600ms vs 1.6s). You actually feel that one. Metadata operations (file-exists, file-attributes) are about 2-3x faster.

But look closer and things get weird. RPC is basically the same speed as stock TRAMP for file writes (243ms vs 246ms). flit is 3x slower than stock TRAMP for running remote commands (67ms vs 21ms for a simple ls). And flit absolutely chokes on large file reads (808ms for a 10MB file vs 191ms for stock TRAMP).

Neither project is a clean win across the board. They each have operations where they’re actually worse than the thing they’re trying to replace.

Warm cache: no performance benefits

TestRPCflitsshx
cached-file-exists571 us132 us228 us
cached-file-attrs323 us145 us214 us
cached-multi-stat (10x)1.50 ms1.70 ms2.15 ms
cached-dir-files1.22 ms330 us520 us

Once data is cached, all three backends return in microseconds. At this scale, the backend is irrelevant – you’re measuring Emacs hash table lookups. And in real usage, a lot of your TRAMP interactions are hitting warm caches (reopening buffers, navigating directories you’ve already listed, etc.).

Git and magit: where it actually gets interesting

This is the test I was most curious about. Magit on remote repos is genuinely painful with stock TRAMP because it runs dozens of git commands sequentially.

TestRPCflitsshx
git rev-parse16.3 ms66.1 ms26.7 ms
git status16.7 ms66.7 ms20.5 ms
git log (20 commits)16.3 ms67.5 ms21.9 ms
git diff –stat15.9 ms66.5 ms19.9 ms
git ls-files16.3 ms66.6 ms21.5 ms
git branch -a15.7 ms68.0 ms20.6 ms
magit-refresh-sim (5 cmds)79.5 ms396 ms118 ms

RPC is consistently the fastest here. flit, on the other hand, is a disaster for git operations.

To be fair, tramp-rpc has a trick this benchmark doesn’t capture: it can batch all those git commands into a single round-trip. That’s where the real magit speedup lives, not in shaving 4ms off individual calls.

So, is it worth it?

For me, probably not. The improvements on a typical SSH connection are real but modest. You save a second on connection setup, a few milliseconds per file operation, and maybe 40ms on a magit refresh. In exchange, you need to compile, deploy, and maintain a server binary on every remote host.

Stock TRAMP isn’t glamorous. But with ControlMaster doing the heavy lifting, it’s doing a more reasonable job than its reputation suggests. Sometimes the boring tool is fine.