Skip to content

SSHFS: mounting remote directories over SSH with FUSE

Mount remote directories over SSH using sshfs/FUSE on Linux, including the connection-reuse and reconnect options that make it usable for more than ad-hoc transfers.

SSHFS mounts a remote directory over SSH using FUSE, presenting it as a local path. It’s the right tool for ad-hoc work — pull a remote project into your editor’s filesystem view, or copy a few files between hosts where rsync feels heavy. It’s the wrong tool for production stateful workloads because every syscall round-trips over the network and the failure modes are unforgiving. This article documents the install, the connection-reuse and reconnect options that make sshfs usable for more than one-off scripts, and the cases where we’d reach for it vs alternatives like NFS or rsync.

How to verify

# Package presence
apt list --installed sshfs 2>/dev/null
which sshfs

# After mounting
mount | grep fuse.sshfs
df -h /mnt/remote
ls /mnt/remote
findmnt /mnt/remote

What’s happening

SSHFS uses the SFTP subsystem of OpenSSH — every filesystem operation (open, read, write, stat, readdir) becomes one or more SFTP requests over the SSH transport. The FUSE library in userspace translates kernel VFS calls into SFTP, and the kernel sees /mnt/remote as a regular filesystem. There’s no kernel module beyond fuse itself; everything filesystem-specific runs as a userspace process.

The latency floor matters. Each stat() is one SFTP round trip, so an ls -l on a directory of 1000 files is 1000 SFTP requests. Over a 50ms WAN link that’s 50 seconds — unusable. The Cipher=aes128-ctr,Compression=no,IdentitiesOnly=yes,ServerAliveInterval=15 combination and SFTP request pipelining help, but the fundamental constraint is “one filesystem operation = one network round trip.” On a LAN it’s fine; over the WAN it’s painful for anything beyond browsing.

Reconnect is the production-grade feature. By default, a network blip kills the sshfs mount and leaves stale handles that won’t unmount cleanly until you fusermount -u. The reconnect,ServerAliveInterval=15,ServerAliveCountMax=3 options tell sshfs to keep the SSH connection alive with keepalives and re-establish on disconnect. Without those, a sleeping laptop or a router reboot leaves a wedged mount.

When to use sshfs: ad-hoc remote access for editing, occasional file transfer where rsync’s two-step (copy then verify) is too much ceremony, a developer’s “mount my home directory into my IDE.” When not to use it: anything stateful, anything with concurrent writers, anything where corruption-on-disconnect is unacceptable. For that, NFS or a real distributed filesystem is the answer.

The procedure

  1. Install sshfs and FUSE (on the client only — the server just needs OpenSSH):

    sudo apt update
    sudo apt install -y sshfs
    sudo modprobe fuse
    lsmod | grep fuse
  2. Create the mount point and verify SSH key-based auth works to the target:

    mkdir -p ~/mnt/remote
    ssh [email protected] 'echo ok'
  3. Basic mount:

    sshfs [email protected]:/data ~/mnt/remote
    ls ~/mnt/remote
  4. Production-shaped mount with reconnect and caching:

    sshfs [email protected]:/data ~/mnt/remote \
      -o reconnect,ServerAliveInterval=15,ServerAliveCountMax=3 \
      -o cache=yes,kernel_cache,large_read \
      -o Compression=no,Cipher=aes128-ctr \
      -o IdentityFile=/home/me/.ssh/id_ed25519,IdentitiesOnly=yes \
      -o uid=$(id -u),gid=$(id -g),allow_other
  5. Add to /etc/fstab for boot-time mounting (note: requires user_allow_other in /etc/fuse.conf for allow_other):

    [email protected]:/data /home/me/mnt/remote fuse.sshfs noauto,x-systemd.automount,_netdev,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,IdentityFile=/home/me/.ssh/id_ed25519,IdentitiesOnly=yes,uid=1000,gid=1000 0 0
  6. Unmount cleanly:

    fusermount -u ~/mnt/remote
  7. If unmount hangs because the mount is wedged:

    sudo fusermount -uz ~/mnt/remote   # lazy unmount
    # or
    sudo umount -l ~/mnt/remote

Common pitfalls

  • Forgetting reconnect — every router blip, wifi sleep, or VPN renegotiation wedges the mount, and the only fix is force-unmount.
  • password_stdin is unsupported on modern sshfs — always use SSH keys with passphrase via ssh-agent, or IdentityFile pointing at an unencrypted key (with appropriate filesystem permissions).
  • cache=yes improves perceived performance but can mask remote changes — a file modified by another client on the server won’t appear locally until the cache TTL expires. Use cache=no for shared-write scenarios.
  • allow_other requires both the user_allow_other flag in /etc/fuse.conf and that the mount be performed by a user with appropriate privileges; mounts done by a non-root user without the flag refuse allow_other.
  • SFTP server compatibility: older OpenSSH versions limited SFTP throughput; sshfs to SFTP-restricted accounts may run into version-specific bugs.

In the engagements we run, sshfs shows up in developer workflows and ad-hoc support tasks — the right thing for low-volume, low-concurrency remote access where setting up NFS or a shared filesystem would be overkill. We document the reconnect options in customer runbooks for the cases where it’s used, but we’d never put a production workload behind it — the failure modes during a network glitch are too unforgiving.