compute
ranked
07 Sept 2026
Nine ways to work on files that live on another machine, ranked by small-file cost
Measured on a 68 ms link: an sshfs read of one 13 KB file costs 372 ms, and 200 of them cost 74 seconds. Nine options, ordered by what they do about that.
By Purvansh Parmar
Checked 2026-09-07
Read 8 min
Entries 9
Your repository lives on a box in another city and your editor lives on your laptop. There are two honest ways to close that gap: move the bytes to the process, or move the process to the bytes. Most people reach for a mount, because a mount is one command and everything downstream keeps working without being told anything changed. I have been running that setup for months. Then I timed it. Reading 200 small JSON files off an sshfs mount took 74 seconds, and 200 files of the same sizes on local disk took 19 milliseconds, a factor of about 3,900 on exactly the work a build tool does thousands of times an hour.
How this was checkedI keep my project trees on a small cloud VM and mount them over sshfs, so everything I build reads across a link with a 68 ms median TCP round trip. Reading 200 randomly chosen session logs, 2.5 MB in total, took 74.4 seconds: 372 ms per file. Two hundred files of identical sizes on local disk took 19 ms. Sequential throughput on a single 1.5 MB file came out at 0.9 MB/s, so the link is not the problem. Per-file setup is. A stat of those same files, once a readdir had warmed the directory cache, cost 0.03 ms, which is why the mount feels fine right up until something opens a file.
What I compared on
- Cost of the first read of a small file across a link with 68 ms round trip time
- Whether file contents, not just attributes, are cached on local disk
- What happens to a process holding the path when the link drops
- How many moving parts you have to operate to keep it working
Leave the files where they are and put the shell, the editor server and the build on the same host.
Wins
Anything taht touches many files: a test run, a grep across the tree, a package install, git status on a large repo. File IO happens at local disk cost because it is local, and the only thing crossing the network is terminal output at a few kilobytes a second.
Loses
Your local tooling stops being local. A GUI app that expects a real path, a language server you only have installed on your laptop, and any process you did not start on the far side will not see the files at all. You also need a session that survives a dropped link, so tmux or mosh moves from optional to mandatory.
19 ms to read 200 small files on local disk against 74.4 s over the mount68 ms median round trip on the link tested
Two-way file sync built for remote development, run by a daemon with one session per directory pair.
Wins
You want the tree on local disk for editor speed while builds or cron keep changing it on the far side. Mutagen watches both ends, propagates in both directions, and its ignore rules understand a source tree, so a dependency directory stays out of the transfer entirely.
Loses
The last release, v0.18.1, landed on 24 February 2025, which is more than eighteen months of silence as of today. Two-way sync also hands you conflict resolution, and one wrong ignore rule will cheerfully replicate a multi-gigabyte build directory across the link before you notice it is happening.
v0.18.1 released 24 Feb 202518 months since the last release
Continuous peer to peer folder sync with no central server and no account to create.
Wins
Several machines that all need the same tree, with none of them designated the source of truth. Traffic is encrypted device to device, direct where it can be and relayed where it cannot, and it keeps working while a peer is offline.
Loses
A folder's default rescan interval is 3600 seconds, so any change the filesystem watcher misses can sit unnoticed for an hour. Every device holds a complete copy and there is no partial checkout, so a 50 GB tree is 50 GB on your laptop whether or not you ever opened it.
rescanIntervalS default 3600fsWatcherDelayS default 10maxConcurrentWrites default 16
A FUSE mount over dozens of storage backends, with a local disk cache you have to switch on yourself.
Wins
Object storage you would rather read as files, or an SFTP host where you need write-back caching. Run it with vfs-cache-mode full and the first read of a file pulls it to disk, after which every read of that file is a local read at local speed.
Loses
The default is vfs-cache-mode off, which is the same no-data-cache behaviour that makes sshfs slow, so out of the box it buys you nothing on this workload. The cache is unbounded by default too: vfs-cache-max-size is off, and entries expire only after vfs-cache-max-age, which is 1h0m0s.
--vfs-cache-mode default off--dir-cache-time 5m0s--vfs-cache-max-age 1h0m0s--attr-timeout 1s
A POSIX filesystem assembled from an object store for data and a database for metadata.
Wins
A shared filesystem that several machines mount at once and that has to behave like a filesystem. It supports flock and fcntl locking, keeps a local cache, and serves metadata operations from your database instead of from the object store.
Loses
You are now operating a metadata engine, whether that is Redis, MySQL, TiKV or SQLite, and its availability is your filesystem's availability. Lose the metadata and the objects left in the bucket are unreadable chunks. Two services to run, where sshfs was one command.
Apache 2.0 licensed2 backing services required: 1 metadata engine and 1 object store
The kernel network filesystem every Unix already speaks, tuned for a datacentre network.
Wins
A LAN, or a VPC where round trips are under a millisecond. Attribute caching, readahead and an in-kernel client put a build tree over NFS on a local network within sight of disk speed, with no daemon of your own to babysit.
Loses
The attribute cache defaults assume a fast link: acregmin 3 seconds, acregmax 60, acdirmin 30, acdirmax 60. Across a 68 ms link every revalidation is a pause you can feel. You also cannot put NFS on the public internet, so a WireGuard tunnel is part of the setup before you mount anything.
acregmin 3sacregmax 60sacdirmin 30sacdirmax 60s
SFTP presented as a filesystem, mounted with one command and nothing installed on the far end.
Wins
Occasional access to a handful of files on a host you already reach over SSH. There is nothing to install remotely and nothing to configure, and it works the moment your key does, which is exactly why so many of these setups start here and never move.
Loses
Measured here at 372 ms to open and read one file of about 13 KB, and 0.9 MB/s sequential on a 1.5 MB file. Network operations run without timeouts by default, so a dropped connection freezes every process touching the mount until you kill the sshfs process, and a force unmount does not release them. The README says the project has no active regular contributors, the newest release is 3.7.6 from May 2024, and the version my distribution ships is 3.7.1, from November 2021.
372 ms per small file read0.9 MB/s sequential0.03 ms per stat with a warm directory cache3.7.6 released 29 May 2024
The Windows file sharing protocol, mounted on Linux through the in-kernel cifs client.
Wins
A Windows or NAS environment where the share already exists and the directory service already decides who can read it. On a LAN, with SMB3 and multichannel, it moves large files perfectly well and needs no new infrastructure.
Loses
The attribute cache timeout defaults to 1 second, which means near constant metadata chatter, and constant metadata chatter is the one thing a high latency link cannot absorb. You can buy the speed back with cache=loose, at the price of the coherency guarantees, which is a bad trade for a tree two processes are writing to.
actimeo default 1 secondSMB3 multichannel needs 2 or more paths to help
An AWS supported FUSE client that maps S3 objects onto file paths for read heavy jobs.
Wins
Feeding a training job or a batch process that reads large objects front to back from a bucket in the same region. It is built for sequential throughput and it is the vendor supported way to do that, which matters when the alternative is a community FUSE driver.
Loses
It is not a filesystem you can build in. Writes have to be sequential and a seek anywhere but the end of the last write fails, existing files cannot be modified in place, rename is unsupported on general purpose buckets, directories cannot be deleted, and there are no symlinks and no file locking. Every metadata operation is a billed request as well.
1 storage class, S3 Express One Zone, supports rename0 support for in-place modification of an existing object
Side by side
| Files live | One small file, first read | Where it breaks |
| SSH remote execution | Remote only | Local disk speed | Local GUI tools cannot see the tree |
| Mutagen | Both, synced | Local disk speed | No release since Feb 2025 |
| Syncthing | Both, synced | Local disk speed | 3600 s default rescan, full copy per device |
| rclone mount | Remote, cached | One round trip, then local | Cache is off by default |
| JuiceFS | Object store | Cache miss, then local | Metadata database is a second thing to run |
| NFSv4 | Remote | Round trip per revalidation | 60 s attribute cache assumes a LAN |
| sshfs | Remote | 372 ms measured | No timeout by default, so drops hang |
| SMB via cifs | Remote | Round trip, 1 s attribute cache | Metadata chatter over a WAN |
| Mountpoint for Amazon S3 | Object store | Fast for big sequential reads | No rename, no in-place write |
Verdict
Run the work on the machine that holds the files. SSH remote execution is not a filesystem, and that is exactly why it wins here: nothing crosses the link except keystrokes, so walking a 2,400 file tree costs what it costs on the host's own disk. Keep sshfs mounted if you have scripts with hardcoded paths you are not going to rewrite today, and go in knowing every read they do costs about a third of a second. If you truly need the files on your laptop, use Mutagen and read from your own disk instead of pretending the network is one.
Sources