Benchmarks
smallfile
sandbox.exec, on a FUSE baseline (libfuse's passthrough_ll),
and on the kernel's own overlayfs, one after the other.
LayerFS against FUSE baseline
vs FUSE baseline- LayerFS
- core at main e5c7aaae05, through the JS SDK
- Tool
- smallfile aa2519de · 4 threads × 25,000 × 4 KiB
- Baseline
- libfuse passthrough_ll 3.14.0, a sibling container on the same VM
- Reference
- kernel overlayfs, the same Sandbox's own /tmp (no FUSE)
- Host
- arm64 Mac · Docker Desktop, linux/arm64, 8 CPUs, 8.3 GB
- Load
- 6.7–11.5 (1 min), three-arm run
Completeness and the Commit
9 / 9 PASS
every operation processed 100% of its 100,000 files
10.4 s
104 µs per file · 410 MB, mountable as history from then on
Against a FUSE baseline
The like-for-like comparison: libfuse’s passthrough_ll (fuse-3.14.0) over a plain directory, writeback off, same tool and arguments, same run. LayerFS is faster in 9 of 9 operations, while also recording every change for the next Commit.
- create6,693 / 3,293 · 2.03×
- read13,176 / 4,365 · 3.02×
- append8,213 / 4,790 · 1.71×
- stat52,136 / 4,868 · 10.71×
- chmod17,275 / 5,114 · 3.38×
- rename4,615 / 2,635 · 1.75×
- delete-renamed5,589 / 4,401 · 1.27×
- mkdir12,349 / 2,934 · 4.21×
- rmdir10,971 / 3,354 · 3.27×
What the rates mean for a tool call
LayerFS time for 1,000 files at the measured rate, four threads. A typical package or source tree touches hundreds to a few thousand files per command.
create
149 ms
unpack or generate 1,000 files
read
76 ms
read 1,000 source files
append
122 ms
append to 1,000 logs
stat
19 ms
stat 1,000 files (a build’s freshness check)
chmod
58 ms
chmod 1,000 files
rename
217 ms
rename 1,000 files
delete-renamed
179 ms
delete 1,000 files
mkdir
81 ms
make 1,000 directories
rmdir
91 ms
remove 1,000 directories
The reference is not like-for-like
Kernel overlayfs is the Sandbox's own overlayfs /tmp: the kernel's in-memory path, no FUSE. It is the ceiling for this host, not a peer:
No FUSE hop
The reference runs inside the kernel. Every LayerFS operation is a FUSE request to its daemon, a round trip every FUSE filesystem pays.
Writes reach the daemon
Kernel writeback caching is off under the FUSE contract, so each buffered write reaches LayerFS; the reference only copies into page cache.
Every change is recorded
LayerFS records each change so a Commit can capture it and mount it again later. The reference keeps nothing once the container goes.
A ceiling, not a peer
Ratios show the cost of those properties against the fastest local path on this host. The like-for-like comparison is the FUSE baseline, libfuse’s passthrough_ll, measured in the same run.
All three arms, beside the kernel path
Files/s as recorded, on one scale. The FUSE baseline sits even further below the kernel path than LayerFS: the gap to the kernel is the cost of FUSE itself.
- create6,693 / 3,293 / 204,225
- read13,176 / 4,365 / 28,651
- append8,213 / 4,790 / 199,550
- stat52,136 / 4,868 / 1,050,826
- chmod17,275 / 5,114 / 973,438
- rename4,615 / 2,635 / 78,914
- delete-renamed5,589 / 4,401 / 174,917
- mkdir12,349 / 2,934 / 69,575
- rmdir10,971 / 3,354 / 173,828
Read with care
A sibling container
A Sandbox cannot host a second FUSE mount (no-new-privileges, no user namespaces), so passthrough_ll runs in a sibling container from the same image, on the same VM and kernel; the tool runs as the same uid 501.
Its own defaults
passthrough_ll runs as root with no credential switch, up to 10 threads and a 1.0 s cache timeout. It keeps nothing beyond the directory: no recording, no Commit.
It slows with size
passthrough_ll finds inodes in one mutex-guarded list, so it slows as the file count grows; part of a lead at 100,000 files is that list. An indexed server (passthrough_hp) was not measured.
Read after the Commit
The LayerFS read ran after the Commit, so it read the committed base rather than the Workspace overlay.
One sample each
One run per operation and arm, host load 6.66-11.51 (1 min). Cache state warm/unknown, not cold. An earlier two-arm run is in the data folder.
This host
Docker Desktop on an arm64 Mac, LayerFS at main e5c7aaae05, smallfile aa2519de, Disposable Store.
Data: benchmark/data/smallfile/v1.0.0/three-arm/ in the LayerFS repository (results, Commit, environment, receipts and the run record).