Cloud Native 15 min read

Designing FUSE: From Kernel VFS to Userspace and JuiceFS Performance

This article explains the evolution of file system architecture from kernel‑level VFS to userspace via FUSE, reviews the historical role of NFS, details JuiceFS's implementation on top of FUSE, and presents benchmark results that demonstrate its high throughput and practical limitations.

Linux Kernel Journey
Linux Kernel Journey
Linux Kernel Journey
Designing FUSE: From Kernel VFS to Userspace and JuiceFS Performance

Kernel File Systems and VFS

Traditional file systems run entirely in kernel space, where privileged code manages core resources such as CPU, memory, disks, and network interfaces. System calls like open, read, and write act as bridges between user programs and the kernel, passing through the Virtual File System (VFS) layer, which provides a uniform interface for many different underlying file system implementations.

Kernel and user space
Kernel and user space

VFS abstracts the details of each concrete file system, allowing Linux to support dozens of file system types while keeping the kernel code stable and well‑tested.

Network File System (NFS) – First Kernel Breakthrough

As single‑machine performance became insufficient for growing workloads, NFS introduced a virtual storage layer that mounts remote directories as local paths. Applications continue to use standard file‑system calls, while the NFS client translates these calls into RPC requests sent over the network to a server that performs the actual operations.

NFS architecture
NFS architecture

This client‑server model inspired the later design of FUSE, which moves the server side into user space.

FUSE – Bringing File Systems to Userspace

In 2001, Miklos Szeredi created FUSE (Filesystem in Userspace), splitting the implementation into a kernel module and a user‑space library ( libfuse). The kernel module registers a character device /dev/fuse and forwards VFS requests to user space; the user‑space daemon processes these requests and returns results via the same device.

FUSE operation diagram
FUSE operation diagram

The request flow consists of three stages:

Request reception : The kernel registers /dev/fuse and the daemon reads requests with read(). If the request queue is empty, the daemon blocks.

Request handling : The daemon parses the packet, invokes the appropriate user‑space handler (e.g., read, write, create), and produces a response.

Result return : The daemon writes the response back to /dev/fuse; the kernel delivers it to the blocked system call, waking the application.

This design decouples kernel and user code, dramatically lowering the barrier to creating new file systems.

JuiceFS – A High‑Performance Distributed File System Built on FUSE

JuiceFS, launched in 2017, targets cloud‑native environments by using object storage as the backend and FUSE as the front‑end interface. After mounting, standard POSIX commands (e.g., ls, cp, mkdir) operate on the remote storage as if it were local.

JuiceFS architecture
JuiceFS architecture

The open‑file workflow is:

Mounting creates a go‑fuse module that opens /dev/fuse and spawns threads to read kernel requests.

An application call (e.g., open) goes through the C library, reaches VFS, and is handed to the kernel FUSE module.

The kernel packages the request and places it in the mount’s queue, waking a go‑fuse thread.

The go‑fuse thread parses the request and invokes the corresponding JuiceFS implementation.

The result is written back to /dev/fuse, waking the blocked application.

Because each request requires a user‑kernel context switch, performance concerns arise. JuiceFS addresses this with multi‑threaded handling and a smooth‑upgrade mechanism that keeps the mount file descriptor stable, allowing version upgrades without unmounting.

Performance Evaluation

On a 1.5 TB memory, 176‑core Intel Xeon machine, a 512 GB sparse file was created and read sequentially with fio to eliminate disk bottlenecks. Results:

Single‑thread bandwidth reached 2.4 GiB/s.

Increasing the thread count scaled linearly; at 20 threads the throughput hit 25.1 GiB/s, sufficient for most real‑world AI workloads.

Benchmark chart
Benchmark chart

JuiceFS also provides a CSI driver for Kubernetes, enabling non‑privileged containers to access the FUSE daemon safely and ensuring data durability in short‑lived pod scenarios.

Conclusion

FUSE decouples kernel and user space, offering developers a flexible way to implement custom file systems without kernel modifications. In cloud and distributed storage contexts, this flexibility enables projects like JuiceFS to deliver high‑performance, POSIX‑compatible storage that scales with modern workloads. Ongoing optimization work aims to further reduce the overhead of user‑kernel transitions and improve reliability.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Linux kerneldistributed storageFUSEvfsJuiceFSperformance benchmarkinguserspace file system
Linux Kernel Journey
Written by

Linux Kernel Journey

Linux Kernel Journey

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.