Benchmarks

smallfile

The distributed-system-analysis small-file workload generator: 4 threads create, read, append, stat, chmod, rename and delete 100,000 files of 4 KiB, then make and remove directories. Each operation runs in a LayerFS v1.0.0 Workspace through 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
KindPerformancesmall filesindustry standard
LayerFSv1.0.0
Ran on
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

LayerFS v1.0.0

9 / 9 PASS

every operation processed 100% of its 100,000 files

one Commit of all 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.

  1. create6,693 / 3,293 · 2.03×
  2. read13,176 / 4,365 · 3.02×
  3. append8,213 / 4,790 · 1.71×
  4. stat52,136 / 4,868 · 10.71×
  5. chmod17,275 / 5,114 · 3.38×
  6. rename4,615 / 2,635 · 1.75×
  7. delete-renamed5,589 / 4,401 · 1.27×
  8. mkdir12,349 / 2,934 · 4.21×
  9. rmdir10,971 / 3,354 · 3.27×
■ LayerFS■ FUSE baselinefiles/s · LayerFS ÷ baseline

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.

  1. create6,693 / 3,293 / 204,225
  2. read13,176 / 4,365 / 28,651
  3. append8,213 / 4,790 / 199,550
  4. stat52,136 / 4,868 / 1,050,826
  5. chmod17,275 / 5,114 / 973,438
  6. rename4,615 / 2,635 / 78,914
  7. delete-renamed5,589 / 4,401 / 174,917
  8. mkdir12,349 / 2,934 / 69,575
  9. rmdir10,971 / 3,354 / 173,828
■ LayerFS■ FUSE baseline■ Kernel overlayfs

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).