---
title: fs-relay — Rootless Linux FUSE filesystem over HTTP and WebSockets, ~10x
  faster than s3fs and fuse-nfs — by Jad Madi (@jadmadi)
description: Pure Go user-space relay created by Muayyad Alsadi that mounts
  remote directories as local Linux FUSE v3 filesystems over standard HTTP and
  WebSockets. It unpacks and packs archives ~10x faster than s3fs and fuse-nfs
  while coordinating POSIX byte-range locks on the server so SQLite and DuckDB
  workloads run safely across hosts without root or VPNs.
href: /project/fs-relay/
author: Jad Madi
category: Developer Tools & Infrastructure
domain: Developer Tools & Infrastructure
status: Upstream Merged
license: "Dual: MIT / WaqfDPL-1.0"
year: "2026"
version: 0.2.0
---

# fs-relay — Rootless Linux FUSE filesystem over HTTP and WebSockets, ~10x faster than s3fs and fuse-nfs

Pure Go user-space relay created by Muayyad Alsadi that mounts remote directories as local Linux FUSE v3 filesystems over standard HTTP and WebSockets. It unpacks and packs archives ~10x faster than s3fs and fuse-nfs while coordinating POSIX byte-range locks on the server so SQLite and DuckDB workloads run safely across hosts without root or VPNs.

## Project Overview

- **Website**: https://jadmadi.net/project/fs-relay/
- **Version**: 0.2.0
- **Live Platform**: https://jadmadi.net/project/fs-relay
- **Repository**: https://github.com/muayyad-alsadi/fs-relay
- **Documentation**: https://github.com/muayyad-alsadi/fs-relay/blob/main/README.md
- **Domain**: Developer Tools & Infrastructure
- **Category**: Developer Tools & Infrastructure
- **Status**: Upstream Merged
- **Year**: 2026
- **License**: Dual: MIT / WaqfDPL-1.0 (permissive)
- **Author**: [@JadMadi](https://x.com/jadmadi)

## Quick Install & Run

### Linux & macOS

```bash
go install github.com/muayyad-alsadi/fs-relay/cmd/fs-relay@v0.2.0 && go install github.com/muayyad-alsadi/fs-relay/cmd/fs-relay-bind@v0.2.0
```

## The Problem It Solves

Sharing directories across machines or coding agents via NFS, SMB, or s3fs requires root privileges or complex firewall rules, suffers from high per-file round-trip latency, and corrupts SQLite databases due to missing or local-only POSIX locks.

## The Solution

A rootless FUSE v3 mount over standard HTTP and WebSockets that batches small-file and directory prefetches, streams large files via splice pipes, and coordinates POSIX byte-range locks on the server so concurrent SQLite writers stay consistent.

## Key Features & Capabilities

- Unpacks and packs archives ~10x faster than s3fs and fuse-nfs via batch reads/readdirs prefetching, 1 MiB write-behind, and raw splice sockets
- Server-authoritative POSIX record locks (getlk, setlk, setlkw, flock) with dedicated SQLite pending, reserved, and shared range counters
- Startup validation, non-blocking -token-file secret loading, and symlink-hardened .fs-relay.lock single-server protection
- Bounded 2-second clean unmount on SIGINT/SIGTERM with interruptible fusermount3 -uz / MNT_DETACH fallback when busy
- Two-phase staged self-updater (update, version, help) with SHA-256 digest verification, permission preservation, and automatic rollback

## How-To Guide

### 1. Install fs-relay and fs-relay-bind

Install both static pure-Go binaries (server and FUSE v3 client) onto your PATH, or build them from a local clone with just build. Ensure fuse3 (fusermount3) is installed on any Linux machine that will mount a share.

```bash
go install github.com/muayyad-alsadi/fs-relay/cmd/fs-relay@v0.2.0
go install github.com/muayyad-alsadi/fs-relay/cmd/fs-relay-bind@v0.2.0
```

### 2. Create a bearer token file and start the server

Write a shared secret to a mode-0600 file so the token never appears in process listings (ps aux), then start fs-relay pointing at a data root. Each namespace is created on demand under ./data/<namespace>/.

```bash
umask 077 && openssl rand -hex 32 > ./token.txt
mkdir -p ./data
fs-relay -listen 127.0.0.1:8080 -data ./data -token-file ./token.txt
```

### 3. Mount a namespace on one or more Linux clients

Create an empty mountpoint directory and run fs-relay-bind. By default it uses a persistent WebSocket for low-latency RPCs and blocking lock wakeups; pass -post if your reverse proxy blocks WebSockets.

```bash
mkdir -p /tmp/demo
fs-relay-bind -url http://127.0.0.1:8080 -ns myproject -token-file ./token.txt /tmp/demo
```

### 4. Run concurrent SQLite or DuckDB workloads across mounts

Point SQLite at the mounted directory using rollback journal mode (DELETE or TRUNCATE, which is SQLite's default). Server-side POSIX byte-range locks serialize writers across multiple mounts and flush/invalidate client caches at lock boundaries.

```bash
sqlite3 /tmp/demo/app.db "PRAGMA journal_mode=DELETE; CREATE TABLE IF NOT EXISTS runs (id INTEGER PRIMARY KEY, host TEXT); INSERT INTO runs (host) VALUES (hex(randomblob(4))); SELECT * FROM runs;"
```

### 5. Unmount cleanly or self-update in place

Press Ctrl+C (SIGINT) or send SIGTERM to fs-relay-bind: it attempts a clean unmount within 2 seconds and falls back to a lazy detach (fusermount3 -uz) if a process still holds an open file. To upgrade both binaries in place with SHA-256 verification and automatic rollback, run fs-relay update.

```bash
fusermount3 -u /tmp/demo
fs-relay update
```

## Upstream Open Source Contribution

- **Target Repository**: muayyad-alsadi/fs-relay
- **Status**: merged
- **Description**: [Muayyad Alsadi](https://github.com/muayyad-alsadi/) ([@muayyadalsadi](https://x.com/muayyadalsadi)) created fs-relay to give Linux machines and cloud sandboxes a fast, rootless remote filesystem over plain HTTP without the per-file latency of s3fs or the fragility of NFS. He invited me to contribute to the project, where we collaborated on multi-mount SQLite POSIX locking, data-root safety, clean unmount handling, and the v0.2.0 release. Read the full background and benchmarks in [Mounting Remote Disks Over Plain HTTP: Contributing to fs-relay](/posts/mounting-remote-directories-over-http/).
- **Pull Requests & Listings**:
  - https://github.com/muayyad-alsadi/fs-relay/pull/3
  - https://github.com/muayyad-alsadi/fs-relay/pull/17
  - https://github.com/muayyad-alsadi/fs-relay/pull/19
  - https://github.com/muayyad-alsadi/fs-relay/pull/20
  - https://github.com/muayyad-alsadi/fs-relay/pull/24
  - https://github.com/muayyad-alsadi/fs-relay/pull/33
  - https://github.com/muayyad-alsadi/fs-relay/pull/34
  - https://github.com/muayyad-alsadi/fs-relay/pull/35
  - https://github.com/muayyad-alsadi/fs-relay/pull/37
  - https://github.com/muayyad-alsadi/fs-relay/pull/38
  - https://github.com/muayyad-alsadi/fs-relay/pull/39
  - https://github.com/muayyad-alsadi/fs-relay/pull/40

## Technical Specifications & Architecture

- **Languages**: Go
- **Frameworks / Libraries**: go-fuse, Google FlatBuffers
- **Architecture**: 5-package pure Go design (CGO_ENABLED=0): FUSE v3 client with batch small-file/dir prefetching and 1 MiB write-behind, FlatBuffers over HTTP/WebSockets, raw splice socket, and server-side POSIX lock table
- **License Model**: Dual: MIT / WaqfDPL-1.0

## Frequently Asked Questions

### Why use fs-relay instead of NFS, SSHFS, or s3fs?

[Muayyad Alsadi](https://github.com/muayyad-alsadi/) ([@muayyadalsadi](https://x.com/muayyadalsadi)) designed fs-relay so remote folders mount over standard HTTP and WebSockets without root, VPNs, or kernel modules, while batching small-file and directory prefetches to run ~10x faster than s3fs and fuse-nfs on source-tree workloads.

### Does fs-relay support concurrent SQLite access across mounts?

Yes, in rollback journal mode (DELETE or TRUNCATE). The server coordinates POSIX byte-range locks across mounts, and fs-relay-bind drains buffered writes before unlocking and invalidates cached bytes on lock grant. WAL mode is not supported because it requires shared memory (mmap) across hosts.

### Do I need root access or kernel modules to run it?

No. Both fs-relay and fs-relay-bind are pure Go static binaries (CGO_ENABLED=0) that run as an unprivileged user on Linux with FUSE v3 (fusermount3).

## Links & References

- Project Page on Crosscurrent Code: https://jadmadi.net/project/fs-relay/
- Full Projects Directory: https://jadmadi.net/projects/
- Author Profile: https://jadmadi.net/about/
