We raised $3M for agent-native runners

Build each architecture on native runners

Run architecture-specific builds on matching hardware to avoid the overhead of emulation.

How companies used this technique

Read what each company changed and follow the original sources.

Build arm64 on native arm64 runners

Confidence's release job built its deployer image for amd64 and arm64 on one x86 runner, compiling the arm64 Rust code under QEMU emulation. The change runs one matrix job per platform, amd64 on ubuntu-latest and arm64 on ubuntu-24.04-arm, pushes each image by digest, and adds a job that combines the digests into a single multi-arch manifest. The QEMU setup step is gone.

The last release run under emulation took 2 hours 28 minutes; a test workflow mirroring the change finished in about 17 minutes of wall-clock time, which the author reports as a ~8.7x speedup. Source

Use it when
A workflow builds arm64 images or binaries on x86 runners through emulation, and native arm64 runners are available to it.
Before applying it
Each architecture gets its own job and pays its own setup, and a final job merges the per-platform digests into one manifest.

Build each container architecture natively

Stripe sync-engine split its Docker build into parallel arm64 and amd64 jobs on matching native GitHub runners, replacing an emulated multi-platform build, and a manifest job combines both with docker buildx imagetools.

Use it when
Cross-architecture emulation dominates a multi-platform image build.
Before applying it
Publish the multi-platform manifest only after every platform build and check succeeds, and keep every supported platform.

Company Playbooks