Files
nfs/docs/BENCHMARKING.md
petrbalvin a9b8039ef7
Test / test (push) Successful in 2m4s
Release / gates (push) Successful in 2m5s
Release / build (amd64, freebsd) (push) Successful in 1m27s
Release / build (amd64, linux) (push) Successful in 1m22s
Release / build (amd64, netbsd) (push) Successful in 1m19s
Release / build (amd64, openbsd) (push) Successful in 1m20s
Release / build (arm64, darwin) (push) Successful in 1m21s
Release / build (arm64, freebsd) (push) Successful in 1m26s
Release / build (arm64, linux) (push) Successful in 1m25s
Release / build (arm64, netbsd) (push) Successful in 1m31s
Release / build (arm64, openbsd) (push) Successful in 1m27s
Release / build (loong64, linux) (push) Successful in 1m37s
Release / build (riscv64, linux) (push) Successful in 1m21s
Release / release (push) Successful in 40s
feat: full NFSv4.2 server and client in pure Go
Assisted-by: GLM 5.3 Flash
2026-09-21 18:51:17 +02:00

2.0 KiB

Benchmarking

How the nfs project is measured. Every number a document, a README or a changelog quotes comes from here and nowhere else.

The method

  • Two levels are measured, and they answer different questions. The backend level benchmarks the internal/nfsfs filesystem layer on its own: what one READ, WRITE, GETATTR or LOOKUP costs against a local directory. The wire level benchmarks whole NFS sessions: the server binary and the client library over a loopback connection, which adds the RPC, XDR and session layers on top of the backend.
  • What is deliberately left out: kernel NFS mounts, the network beyond loopback, and any comparison against other NFS servers. Those are interop questions, not benchmark questions.
  • The machine is idle, named, and stays the same across comparable reports.
  • The toolchain is named with its version and its build flags.
  • Comparisons run inside one process, with the order of the two sides alternated where a comparison is the point. Differences under two percent are noise, not results.
  • A change is measured against its baseline, not against a memory of how fast it used to be. The baseline run is part of the measurement, and both sides land in the same report.

Running

just bench

The recipe sweeps ./internal/... with -benchmem -count=5.

A first look at one target, before the full battery is worth the time:

go test -run '^$' -bench 'BenchmarkRead64K' -benchtime=1x ./internal/nfsfs

The full battery runs once, deliberately, on an idle machine. A benchmark command is capped at about two minutes per round; longer sweeps are split.

Reports

Reports live in docs/_results/, one file per measurement round, named YYYY-MM-DD-subject.md, and follow BENCHMARK_TEMPLATE.md. A report carries its numbers, its machine, its toolchain and the exact command. A number without its provenance is not a result, and a performance claim without a report behind it is left out of the documentation rather than softened into an adjective.