raft / docs

Native images and boot performance

Raft builds Debian 13 system container images for native ARM64 and AMD64 hosts. The installer, base image, and Node archive match the host CPU architecture. These are separate native images, not emulation layers.

Timings depend on software, image state, hardware, host load, and network transport. These measurements do not compare Raft with hosted Boat.

Native CI comparison

Verified native run, 2026-10-06. Five samples per architecture on 4-CPU runners with 1 guest CPU and 2 GiB guest RAM:

Controller-visible medianARM64 runnerAMD64 runner
Create returns handle0.425 s0.659 s
Create accepts a command0.866 s1.375 s
Create has Docker ready2.280 s3.035 s
Resume accepts a command0.951 s1.489 s
Resume has Docker ready2.626 s3.049 s
Desktop starts after create1.115 s1.592 s
Compressed image1.79 GiB1.86 GiB

Raw samples and p95 distributions are recorded in ARM64 report and AMD64 report. Measurements reflect runner hardware and transport differences, not inherent architecture performance.

Native CI validates builds, workspaces, and clean exports. Imports must match host CPU architecture; cross-architecture recovery is not supported.

Baseline measured on 2026-10-06

Three-sample medians from two 2-CPU ARM64 hosts with pre-warmed image volumes. Raw samples are preserved in host A and host B.

Controller-visible operationARM64 host AARM64 host B
Create returns handle0.864 s2.906 s
Create accepts a command1.918 s6.936 s
Create has Docker ready3.941 s10.753 s
Resume returns1.056 s3.889 s
Resume accepts a command1.851 s8.213 s
Resume has Docker ready3.917 s11.653 s
Desktop starts after create2.602 s7.631 s
Desktop starts after resume2.430 s7.669 s
Separate host SSH request0.397 s3.556 s

Network transport latency dominates the delta between hosts. This is not an ARM64 versus AMD64 benchmark, nor a comparison against hosted Boat.

Measured changes on the same ARM64 host

  • SSH key generation: Generates only the advertised Ed25519 host key on first boot, reducing SSH unit startup on host A from 1.898 s to 0.202 s.
  • Desktop polling: Waits for an active X server response rather than sleeping for a fixed second.
  • Image footprint: Omits coding-agent packages. The candidate ARM64 image is 1,920,185,312 bytes versus 2,626,705,196 bytes for baseline (about 27% smaller).
  • Volume pre-warming: Pre-warming the storage volume avoids an initial 82.1 s unpack delay on first use.

Three samples per image on host A give the following comparison. The candidate report preserves all samples.

MeasurementBaselineCandidate
Compressed image2.45 GiB1.79 GiB
SSH unit, first sample1.898 s0.202 s
Create has Docker ready, median3.941 s4.302 s
Resume has Docker ready, median3.917 s3.973 s
Desktop startup inside guest, median1.431 s0.537 s

Warm Docker readiness remains about 4 seconds. These results do not show an overall warm boot speedup; SSH key generation and desktop startup improved.

Desktop benchmarks measure three internal stop/start cycles inside the guest from systemctl start to HTTP 200 and RFB greeting, showing about 62% less startup time in local measurements. Local desktop timing excludes SSH delay; controller-visible timing includes network transport overhead and shows a smaller change.

The candidate passed lifecycle and headed-browser E2E suites on Ubuntu 22 ARM64, and extended suites with all 31 tool checks on Ubuntu 24 ARM64 and AMD64. Fresh-host testing resolved Chromium user-namespace policies and bridge peer filtering.

Benchmark method

python3 deploy/benchmark-boot.py --location lab --samples 5 --desktop > boot.json

The benchmark creates and destroys dedicated test boxes with 1 CPU and 2 GiB RAM. Each sample measures creation, then stops and resumes the same box. It records CLI return, command execution, and Docker API readiness from request initiation.

Desktop timing measures on-demand requests requiring both noVNC HTTP 200 and an RFB protocol greeting. Reports include median, minimum, maximum, nearest-rank p95, SSH round-trip time, image size, and systemd boot critical chain.

Measurements assume the image is pre-downloaded. A first use after import or cache eviction can still unpack Incus's optimized storage volume. Timings are software-dependent, varying with installed packages and services, image state, host hardware, load, and transport overhead.

Small sample sets are exploratory; with three or five samples, nearest-rank p95 is effectively their maximum. They do not measure image downloads, host reboots, process-memory restoration, or remote browser rendering.

Build and verify

Image build, publication, and artifact details

Run the image builder on each native host. To preserve an existing image, specify a new alias such as --alias raft-dev-next. Building a candidate does not modify the pinned fingerprint in controller configuration.

After publication, the builder creates and deletes a cache-preparation instance to populate Incus's storage volume before reporting readiness. Imported archives or use after cache eviction can still require a slow first unpack.

The native images workflow runs on GitHub ubuntu-24.04 and ubuntu-24.04-arm runners. It builds each image, runs extended lifecycle tests and all 31 developer tool checks, measures startup, and exports clean templates with SHA-256 checksums.

Successful CI runs attach seven-day artifacts (raft-dev-amd64 and raft-dev-arm64), which require a GitHub login to download. Small boot-results-amd64 and boot-results-arm64 artifacts contain only reports.

Versioned public images are published under releases after recovery and fresh-host validation; public release assets do not expire on the seven-day CI schedule. Each archive must be imported into a host of the matching CPU architecture.

The CI runner uses a sparse Btrfs pool on an ephemeral VM and does not certify the 80 GiB production free-disk preflight. Pinned images retain their contents until you configure a new fingerprint.

On this page