Engineering · footprint ladder

Footprint of a MoQ relay across deployment models

The disk column is grounded in the actual binaries on the box; the boot and memory columns come from this project's measured numbers. The relay itself is identical across every row — only the platform underneath changes.

measured here measured on this project's hardware typical industry figures, not measured on this box
Model Disk image Memory (working set) Boot: OS Boot: app Cold → serving
Container Docker / Kubernetestypical ~60–120 MB ~30–50 MB 0shares host kernel ~ms ~tens of ms1
microVM + full Linux e.g. fly.io / Firecrackertypical ~100–150 MB ~50–100 MBVMs sized 256 MB–1 GB ~100–125 ms ~ms ~125–175 ms
Unikraft binary-compat mode2measured here ~40–55 MB ~63 MB ~38–39 ms ~43 ms ~82 ms
Unikernel, native TinyMoQmeasured here 11.5 MB ~19 MB ~15 ms ~1 ms ~35 ms
Reference binaries on disk (exact): the native Linux relay binary = 40.4 MB (unstripped, dynamically linked — also needs glibc + ld-linux at runtime); the native unikernel image = 11.5 MB (fully static, nothing else needed). The host-side VMM is separate from the guest image and isn't counted in these figures.

1 Cold → serving excludes orchestration (image pull / scheduling), which adds seconds.
2 Unikraft also supports native (compiled-in) builds, which are substantially smaller and faster than the binary-compat figures shown here. This row reflects Unikraft running the unmodified Linux binary. Reaching those native figures is specialized work, not a recompile: the relay must be built against Unikraft's native API (no Linux syscall shim), and QUIC's UDP datapath and async runtime need low-level fixes in the kernel's socket and scheduler — the porting work we focus on.

How to read it

Boot is the whole story

It's where the models diverge by ~100×: containers pay 0 (shared kernel), the native unikernel ~15 ms, a binary-compat unikernel ~39 ms, full-Linux microVMs ~100–125 ms. App init is ~1–few ms everywhere — it's the same relay; the platform doesn't change it.

Memory is the other real axis

Native unikernel ~19 MB vs binary-compat unikernel ~63 MB vs full-Linux microVM ~50–100 MB+. That's the density lever — roughly 3–5× more relays per host than a full-Linux microVM.

Size: native vs binary-compat

The native unikernel compiles the relay straight into the kernel image → one 11.5 MB static binary with no external dependencies. Unikraft in binary-compat mode runs the unchanged 40 MB Linux binary on a loader shim → bigger and still glibc-dependent. (That 40 MB binary is unstripped; stripping roughly halves it, but it still needs glibc — the native image needs nothing.)

What's apples-to-oranges

Containers and microVMs run the stock Linux binary (zero porting — what fly.io / Kubernetes do); the unikernel rows required compiling/porting the relay and fixing low-level bugs. The table compares the artifacts, not the effort.