Native ARM64 Runners for GitHub Actions

WarpBuild provides native Linux ARM64 GitHub Actions runners from 2 to 32 vCPU at $0.003 to $0.048 per minute. Labels, prices, images, and setup.

Last verified:

WarpBuild runs native Linux ARM64 runners for GitHub Actions in five sizes, from 2 vCPU to 32 vCPU, on Ubuntu 24.04 and Ubuntu 26.04 images. A job moves onto one by changing its runs-on label to a warp-ubuntu-latest-arm64-<size> value, and the runner bills at $0.003 to $0.048 per minute depending on the size you pick.

Native means the ARM64 instructions execute on ARM64 silicon. There is no QEMU translation layer between your compiler and the CPU, so go build, cargo build, docker build --platform linux/arm64, and an ARM64 test suite all run the way they run on an ARM64 production host.

This page lists every Linux ARM64 label WarpBuild registers, the per-minute rate for each one, the two image differences worth knowing about before you switch, and three worked cost models. WarpBuild provides Linux x64, Linux ARM64, macOS, and Windows runners, so a repository that needs both architectures uses one provider and two labels.

Catalog

Ten Linux ARM64 labels are live. Five carry Ubuntu 24.04, five carry Ubuntu 26.04, and the latest labels resolve to the Ubuntu 24.04 line.

LabelOSvCPUMemoryStoragePriceAliases
warp-ubuntu-latest-arm64-2xUbuntu 24.0428GB150GB SSD$0.003/minutewarp-ubuntu-2404-arm64-2x
warp-ubuntu-latest-arm64-4xUbuntu 24.04416GB150GB SSD$0.006/minutewarp-ubuntu-2404-arm64-4x
warp-ubuntu-latest-arm64-8xUbuntu 24.04832GB150GB SSD$0.012/minutewarp-ubuntu-2404-arm64-8x
warp-ubuntu-latest-arm64-16xUbuntu 24.041664GB150GB SSD$0.024/minutewarp-ubuntu-2404-arm64-16x
warp-ubuntu-latest-arm64-32xUbuntu 24.0432128GB150GB SSD$0.048/minutewarp-ubuntu-2404-arm64-32x
warp-ubuntu-2604-arm64-2xUbuntu 26.0428GB150GB SSD$0.003/minutenone
warp-ubuntu-2604-arm64-4xUbuntu 26.04416GB150GB SSD$0.006/minutenone
warp-ubuntu-2604-arm64-8xUbuntu 26.04832GB150GB SSD$0.012/minutenone
warp-ubuntu-2604-arm64-16xUbuntu 26.041664GB150GB SSD$0.024/minutenone
warp-ubuntu-2604-arm64-32xUbuntu 26.0432128GB150GB SSD$0.048/minutenone

Memory scales at 4GB per vCPU across the whole ladder, and storage stays at 150GB SSD at every size. Runner storage is ephemeral and is deleted when the runner terminates, so anything you want to keep goes to an artifact, a cache entry, or a registry before the job ends. The full matrix, including the x64, macOS, and Windows lines, lives in the cloud runners documentation.

Image contents

The Ubuntu 24.04 ARM64 image is compatible with GitHub's Ubuntu 24.04 ARM64 runner image, and GitHub publishes the tool inventory for that image in the partner runner images repository. The Ubuntu 26.04 ARM64 image tracks GitHub's Ubuntu 26.04 ARM64 image the same way. Node, Python, Go, Rust, Docker, the AWS CLI, and the rest of the standard inventory are present, so actions/setup-* steps resolve against preinstalled versions instead of downloading them. The per-image tool lists are indexed in the preinstalled software documentation.

Tailscale ships on every runner image. The daemon stays stopped until networking is configured for the runner, so an ARM64 job that never touches networking pays no startup cost for it.

Two image caveats

The work dir differs from GitHub's. The Ubuntu 24.04 ARM64 images set the work dir to /runner/_work. GitHub-hosted ARM64 runners use /home/runner/work/ for the same image. Any workflow, script, or Dockerfile that hardcodes /home/runner/work/... breaks on this image. Read GITHUB_WORKSPACE, RUNNER_WORKSPACE, or ${{ github.workspace }} and the same workflow runs on GitHub-hosted runners and on WarpBuild runners without a branch in the logic.

Ubuntu 22.04 ARM64 is gone. The ARM64 images for Ubuntu 22.04 were deprecated on March 31, 2025. There is no warp-ubuntu-2204-arm64-<size> label to fall back to. Jobs that were pinned to Ubuntu 22.04 on ARM64 move to warp-ubuntu-latest-arm64-<size> for Ubuntu 24.04 or to warp-ubuntu-2604-arm64-<size> for Ubuntu 26.04. The Ubuntu 22.04 x64 labels still exist, so a mixed repository can hold its x64 jobs on 22.04 while the ARM64 jobs move forward.

What runs on ARM64 and what does not

Cache is enabled by default on Linux runners, ARM64 included, so actions/cache and the dependency caching built into actions/setup-* work with no extra configuration. Snapshot runners cover Linux x64 and Linux ARM64, which means an ARM64 job can boot from a captured VM state instead of reinstalling a heavy toolchain on every run.

Nested virtualization is the exception. Workloads that need /dev/kvm, such as Android emulator jobs, are not currently supported on ARM64 runners. Those jobs belong on the x86-64 runners, where the nested-virtualization.enabled=true dynamic label grants KVM access. If you need nested virtualization on ARM64, contact support before you plan the migration.

Pricing

ARM64 costs less per minute than x64 at every size in the WarpBuild catalog. The table below puts the two ladders side by side so the delta at each size is visible.

vCPUARM64 labelARM64 $/minutex64 labelx64 $/minuteDelta per minute
2warp-ubuntu-latest-arm64-2x$0.003warp-ubuntu-latest-x64-2x$0.004$0.001
4warp-ubuntu-latest-arm64-4x$0.006warp-ubuntu-latest-x64-4x$0.008$0.002
8warp-ubuntu-latest-arm64-8x$0.012warp-ubuntu-latest-x64-8x$0.016$0.004
16warp-ubuntu-latest-arm64-16x$0.024warp-ubuntu-latest-x64-16x$0.032$0.008
32warp-ubuntu-latest-arm64-32x$0.048warp-ubuntu-latest-x64-32x$0.064$0.016

Memory and storage are identical between the two ladders at each size, so the delta is architecture pricing rather than a smaller machine.

Against GitHub's published arm64 rates

GitHub publishes its own per-minute rates for arm64 runners on the GitHub Actions per-minute rate list. The rates below were checked on 2026-08-13.

vCPUWarpBuild $/minuteGitHub-hosted arm64 $/minuteDifference per minuteDifference per 10,000 minutes
2$0.003$0.005 (actions_linux_arm)$0.002$20.00
4$0.006$0.008 (linux_4_core_arm)$0.002$20.00
8$0.012$0.014 (linux_8_core_arm)$0.002$20.00
16$0.024$0.026 (linux_16_core_arm)$0.002$20.00
32$0.048$0.050 (linux_32_core_arm)$0.002$20.00

The gap holds at $0.002 per minute across the ladder, which works out to $20 for every 10,000 runner minutes at any size. As a share of GitHub's rate that is 40 percent lower list price at 2 vCPU, 25 percent at 4, 14 percent at 8, 8 percent at 16, and 4 percent at 32. Two billing details from GitHub's billing concepts page shape the real bill: a plan's included minutes stop applying once a job lands on one of GitHub's larger runners, and GitHub charges for larger runner minutes on public repositories as well.

Minutes count alongside the rate. WarpBuild pricing is purely usage based. There is no base subscription fee, no platform fee, and no seat fee. The full rate card, including cache and snapshot line items, is on the pricing page.

Worked model: a Go service test suite

A backend team runs 1,800 jobs a month at roughly 7 minutes each, which is 12,600 runner minutes. The suite is architecture agnostic and the service already deploys to ARM64 hosts.

  • warp-ubuntu-latest-arm64-4x at $0.006 per minute: 12,600 x $0.006 = $75.60 per month
  • warp-ubuntu-latest-x64-4x at $0.008 per minute: 12,600 x $0.008 = $100.80 per month
  • GitHub-hosted Linux 4-core arm64 at $0.008 per minute: 12,600 x $0.008 = $100.80 per month (GitHub pricing, checked 2026-08-13)

Moving the label from x64 to ARM64 takes the monthly runner line from $100.80 to $75.60, a difference of $25.20 per month and $302.40 over a year on the same job count and the same minutes. Signup includes $10 free credits, which covers 1,667 minutes on warp-ubuntu-latest-arm64-4x or 3,333 minutes on warp-ubuntu-latest-arm64-2x before a card is charged.

Worked model: a multi-arch container image

A release pipeline publishes linux/amd64 and linux/arm64 images on every push to main, at 700 pushes a month. Each architecture leg takes about 9 minutes on an 8 vCPU runner, and a short manifest job stitches the two digests together.

  • amd64 leg on warp-ubuntu-latest-x64-8x: 9 x $0.016 = $0.144
  • arm64 leg on warp-ubuntu-latest-arm64-8x: 9 x $0.012 = $0.108
  • manifest job on warp-ubuntu-latest-arm64-2x: 1 x $0.003 = $0.003
  • per push: $0.255, or $178.50 per month across 700 pushes

Now price the emulated alternative, where both platforms build on one warp-ubuntu-latest-x64-8x at $0.016 per minute and the arm64 layers go through QEMU. The native arm64 leg costs $0.108. An emulated arm64 leg on the x64 runner reaches $0.108 at 6.75 minutes. So the emulated build costs more than the native build from 6 minutes 45 seconds onward, before counting the extra wall-clock time the pipeline holds open. That break-even sits below the 9 minutes the leg already takes natively.

Worked model: the size ladder at fixed volume

The same 10,000 minutes a month, priced at each ARM64 size, with GitHub's published arm64 rate beside it for reference (GitHub pricing, checked 2026-08-13).

RunnerWarpBuild monthlyGitHub-hosted arm64 monthlyMonthly difference
2 vCPU$30.00$50.00$20.00
4 vCPU$60.00$80.00$20.00
8 vCPU$120.00$140.00$20.00
16 vCPU$240.00$260.00$20.00
32 vCPU$480.00$500.00$20.00

Sizing up multiplies the rate but keeps the same $20 per 10,000 minutes gap, so the decision about which size to run is a wall-clock decision rather than a pricing one. If a 16 vCPU runner finishes a job in fewer than half the minutes an 8 vCPU runner needs, the larger label costs less per job. Time that on your own workload before committing a size across the repository.

Configuration

Switching a job to ARM64 is a runs-on change. Nothing else in the workflow file has to move.

name: test
on:
  push:
    branches: [main]
  pull_request:

jobs:
  unit-tests:
    runs-on: warp-ubuntu-latest-arm64-4x
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: "1.24"
          cache: true
      - run: go build ./...
      - run: go test -race ./...

Use the versioned label when you want the OS pinned. warp-ubuntu-2604-arm64-8x stays on Ubuntu 26.04 through image updates, while warp-ubuntu-latest-arm64-8x follows the Ubuntu 24.04 line and its alias warp-ubuntu-2404-arm64-8x says the same thing explicitly. Teams with reproducibility requirements pin the versioned label and schedule their own upgrade.

Building both architectures natively

A matrix over runner labels gives each architecture its own native machine and keeps the build definition in one job.

name: images
on:
  push:
    branches: [main]

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        include:
          - arch: amd64
            runner: warp-ubuntu-latest-x64-8x
          - arch: arm64
            runner: warp-ubuntu-latest-arm64-8x
    runs-on: ${{ matrix.runner }}
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/${{ matrix.arch }}
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}-${{ matrix.arch }}

  manifest:
    needs: build
    runs-on: warp-ubuntu-latest-arm64-2x
    steps:
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - run: |
          docker buildx imagetools create \
            --tag ghcr.io/${{ github.repository }}:${{ github.sha }} \
            ghcr.io/${{ github.repository }}:${{ github.sha }}-amd64 \
            ghcr.io/${{ github.repository }}:${{ github.sha }}-arm64

The manifest job does registry API work and no compilation, so the 2 vCPU label at $0.003 per minute is the right size for it. The multi-platform Docker build guide covers cache scoping and digest-based manifests for this pattern in more depth.

Handling the work dir difference

The workspace path is the one thing that surprises people on their first ARM64 run. Ask the runner for the path instead of assuming it.

jobs:
  package:
    runs-on: warp-ubuntu-latest-arm64-8x
    steps:
      - uses: actions/checkout@v4
      - name: Report workspace paths
        run: |
          echo "GITHUB_WORKSPACE=$GITHUB_WORKSPACE"
          echo "RUNNER_WORKSPACE=$RUNNER_WORKSPACE"
      - run: make dist
      - uses: actions/upload-artifact@v4
        with:
          name: dist-arm64
          path: ${{ github.workspace }}/dist

On the Ubuntu 24.04 ARM64 image GITHUB_WORKSPACE resolves under /runner/_work, and on a GitHub-hosted runner it resolves under /home/runner/work/. A workflow that reads the variable produces the same artifact on both. Grep your repository for /home/runner/work before the switch: Dockerfiles with absolute COPY paths, cache keys built from absolute paths, and shell scripts that cd into a fixed directory are the usual offenders.

Native builds against emulated builds

Emulation is how a single x64 runner produces an ARM64 artifact. QEMU registers with binfmt_misc, and every ARM64 instruction the build emits is translated to x64 at run time. Compilers, linkers, and test suites are instruction heavy by nature, which is why an emulated build spends its time in the translation layer rather than in the toolchain. Native ARM64 runners remove that layer: the toolchain issues ARM64 instructions and the CPU executes them.

Correctness is the second reason teams move. An emulated build can hide architecture-specific behavior around atomics, page size, unaligned access, and CPU feature detection, and those defects then surface in production on ARM64 hosts. A native ARM64 runner exercises the same instruction set your servers run. The multi-arch cost model above shows where the pricing crossover between a native leg and an emulated leg sits.

The ARM64 migration guide walks through the move job by job, including how to keep an x64 job and an ARM64 job green in the same workflow while you cut over.

Beyond WarpBuild-hosted ARM64

If the runners have to live in your own cloud account, BYOC runs on AWS, GCP, and Azure, and Terraform support exists for BYOC on AWS. The label contract is the same, so a workflow that already points at ARM64 labels does not change shape when the capacity moves into your account.

Where to go next

FAQ

What do WarpBuild ARM64 runners cost per minute?

Linux ARM64 runners cost $0.003 per minute at 2 vCPU, $0.006 at 4 vCPU, $0.012 at 8 vCPU, $0.024 at 16 vCPU, and $0.048 at 32 vCPU. Every size is $0.002 per minute below the rate GitHub publishes for its own arm64 runner at the same core count, checked on 2026-08-13.

Do WarpBuild ARM64 runners use the same work directory as GitHub-hosted runners?

No. The Ubuntu 24.04 ARM64 images set the work dir to /runner/_work. GitHub-hosted ARM64 runners use /home/runner/work/ for the same image. Read the path from GITHUB_WORKSPACE or RUNNER_WORKSPACE instead of hardcoding it, and the workflow runs unchanged on both.

Can I still run Ubuntu 22.04 ARM64 images?

No. The ARM64 images for Ubuntu 22.04 were deprecated on March 31, 2025. Move those jobs to warp-ubuntu-latest-arm64-<size> for Ubuntu 24.04 or warp-ubuntu-2604-arm64-<size> for Ubuntu 26.04. The Ubuntu 22.04 x64 labels are unaffected.

Does nested virtualization work on ARM64 runners?

Workloads that need nested virtualization, such as Android emulator jobs, are not currently supported on ARM64 runners. Run those jobs on the x86-64 runners with the nested-virtualization.enabled=true label, and contact support if you need nested virtualization on ARM64.

Start with $10 in free credits

Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.