Arm (arm64) runners for GitHub Actions

Run GitHub Actions and GitLab CI jobs on Arm (AWS Graviton) machines in your own account: the label, the prices, and building for two architectures.

A job that says runs-on: superci-arm64 gets an Arm machine in your own AWS account: one of AWS’s Graviton machines.

jobs:
  test:
    runs-on: superci-arm64
    steps:
      - uses: actions/checkout@v5
      - run: uname -m   # aarch64

On GitLab it is a tag: tags: [superci-arm64].

Sizes

superci-arm64 is 4 CPUs and 8 GB. Sizes are asked for as on x64, in any order:

LabelMachine
superci-arm644 CPUs, 8 GB (c8g.xlarge)
superci-8cpu-arm648 CPUs, 32 GB (m8g.2xlarge)
superci-16cpu-arm6416 CPUs, 64 GB (m8g.4xlarge)
superci-32cpu-arm64-ondemand32 CPUs, 128 GB (m8g.8xlarge), never a spot machine

When the newest Graviton machines have no spot capacity, the generation before (c7g, m7g) is tried next.

What it costs

Arm machines cost less than x64 ones of the same size, on GitHub and on AWS. A minute on a machine with the memory of GitHub’s runner (4 GB for each CPU), with the disk and public address counted in:

CPUsGitHub-hosted, arm64AWS spotAWS on-demand
2$0.005$0.0008$0.0017
4$0.008$0.0014$0.0032
8$0.014$0.0020$0.0062
16$0.026$0.0046$0.012
32$0.050$0.0091$0.024

AWS’s prices are for us-east-1 on 12 October 2026; spot prices move through the day. At 4 CPUs the row is superci-4cpu-arm64, with 16 GB like GitHub’s; superci-arm64 alone has 8 GB and costs a little less. The calculator works out a month.

What to know

  • Only AWS. Cloudflare’s containers and Modal’s sandboxes are x64, so they are passed by for an Arm job.
  • Linux only. There are no Windows or GPU machines on Arm here; those labels are refused with a message.
  • What a job finds: the arm64 build of the same image as on x64, with the tools of GitHub’s own Ubuntu 24.04 runners. Docker is there.
  • Your tools must have an Arm build. Most do. An action that downloads an x64 program fails on Arm with “exec format error”.

Arm as your default

Under Workflows in the dashboard you can make arm64 the default machine. Then runs-on: superci gets an Arm machine, and superci-x64 asks for x64. Windows and GPU labels keep x64 either way.

Building for both

A matrix gives each architecture its own machine, with no emulation:

jobs:
  build:
    strategy:
      matrix:
        arch: [x64, arm64]
    runs-on: superci-${{ matrix.arch }}
    steps:
      - uses: actions/checkout@v5
      - run: docker build -t app:${{ matrix.arch }} .

This is much faster than building an Arm image on an x64 machine through QEMU.