crates/k7d/src/latency.rs (the single source of truth, imported by the tests) and are documented in LATENCY_BUDGETS.md. If a number here drifts from those files, trust the tests. Budgets are set at roughly 2× the typical observed value.
Cluster-tree fork budgets are asserted on the daemon’s own latency_ns, not on the client’s round trip around the Unix socket. Tests print both; a client RTT over budget while the daemon stays under is a finding, not a failure.
Hardware
One pinned bare-metal node (~€40/month Hetzner) used for all figures:Two clocks
Headline results — minimal CI guest
Inner-k3s add-on profiles
Same 3-VM fixture with one stock add-on switched on, plus load churn. Deltas are against the ~104 ms lean baseline. All share the 1 s budget except ArgoCD, which gets its own 2 s.Headline results — Ubuntu nodes
Stock Ubuntu 24.04 root disk, systemd, distro kernel; 3 VMs at 2 GiB / 2 vCPU unless noted. Boot ceilings are loose hang detectors (600 s), not 2× typical. Every fork row reuses one 1 s ceiling, which is also the sub-second target; missing it is a recorded finding, not a silent pass.
Six CoW disks and twice the guest RAM (Longhorn) still fork inside the ceiling the 2 GiB clusters were measured against: fork cost tracks the number of devices and page tables, not the volume of storage behind them. The pull is the long pole every time, not the fork.
Keyframes: O(divergence)
A fork point below the root clones the nearest ancestor’smemory.bin with FICLONE and writes only that node’s dirty pages. 3 × 2 GiB Ubuntu k3s, 30 s of divergence each; ceiling 4.5 s (~2× the worst level):
Test:
test_keyframe_cost_ubuntu_divergence_levels. The bytes are the daemon’s base_disk_bytes; du and stat cannot measure a reflinked file. Neither the keyframe nor the full dump it replaces is fsynced — syncing a patched reflinked file costs 2–5 s per member because every written page breaks a shared extent.
Time warp
An 8.7-minute guest-time episode on a fresh 3-node Ubuntu k3s cluster, three runs per arm (make warp-bench, a Criterion bench kept out of make check for its runtime):
The dilation N sweep (compression exactly N through 16; extra probe failures 0 / 0 / 0 / 3 / 19 / 32 for N ∈ ) and the fork-of-a-dilated-VM tests need the carried KVM patch loaded (
make dilation-install; utils/kvm-dilation/) and are kept out of make check. See Time warp.
Full budget table (minimal guest)
Reproduce
On a node with the repo and toolchain installed (seeHACKING.md for the remote loop):
How the fast path was won
Before the block-rootfs work, cluster pods carried a virtiofs share for the k3s hostPath — so every fork forced a full memory copy of 3 × ~3.2 GiB, landing at ~2 s typical. Moving read-only hostPath mounts to cached erofs images on virtio-blk (zero virtiofs shares) let every member forkMAP_PRIVATE + dirty-page CoW: ~105 ms under a 1 s budget. The share-less fork prep also preserves the source’s vsock CID, so kubectl exec against the source still works after adopt/fork.
The Ubuntu clock is a different guest — systemd and a full distro rootfs instead of a busybox initramfs — through the same VMM. Its root disk forks as a reflink on the daemon’s XFS (~2500 shared extents per child), so the fork is CoW on disk as well as memory.
Comparison (honest)
What we are not claiming
- Firecracker-beating cold boot (we boot once, then fork).
- “<5 MB per instance” density (our guests run kubelet).
- That the virtiofs era (~2 s full-copy) was the intended steady state — it is now the explicit fallback for read-write hostPath only.
- That dilation is free — it is a measured, bounded fidelity cost, and the jump policy exists because it has none.
