Using High Cost-Performance and Power-Efficient Arm-Based GitHub Actions Runner
To reach a broader audience, this article has been translated from Japanese.
You can find the original version here.
Introduction
#Arm-based Actions Runner has entered public beta. Arm-based Linux / Windows runners are now available.
Actions: Arm-based linux and windows runners are now in public beta
GitHub's blog mentions that Arm technology helps reduce data center power consumption. For Windows runners, it seems that GitHub and Arm are partnering to provide Windows VM images[1].
Arm64 on GitHub Actions: Powering faster, more efficient build systems
The appeal for us users is its price, which is 37% cheaper compared to x64 runners. The pricing table is available below.
Per-minute rates | About billing for GitHub Actions - GitHub Docs
Registering Arm-Based Runner to Organization
#Arm-based Runner is available for organizations on paid plans (Team and above).
Select Organization Settings -> Actions -> Runners, and click the New runner
button on the Runners page.
Click New GitHub-hosted runner
.
The UI for creating a runner will be displayed. Linux ARM64
and Windows ARM64
can be selected as Beta.
For now, I set it to the minimum spec Linux ARM 64, Ubuntu 22.04, 2-core 8GB RAM machine, named it linux-arm64
, and clicked Create runner
.
The runner was set up and available immediately.
Speed Comparison
#In addition to the above Arm Runner, I created a minimum configuration x64 Runner named linux-x64
for comparison.
This comparison was conducted in a private repository. Initially, I thought of specifying ubuntu-latest
for the x64 Runner, but I couldn't find the specs for private repository runners in GitHub's English documentation, even though they are listed in the Japanese documentation. Therefore, I decided to create it with equivalent specs for comparison.
I prepared the same workflow used in the previous article "Trying High-Spec Larger Runners in GitHub Actions" for benchmarking.
Building an Electron App
#This workflow builds an Electron app. As in the previous article, it builds the Electron sample published by mamezou-tech and runs it on linux-x64
and linux-arm64
runners.
name: Build Electron App
on:
workflow_dispatch:
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [linux-x64, linux-arm64]
steps:
- uses: actions/checkout@v4
with:
repository: 'mamezou-tech/electron-example-browserview'
path: electron-example-browserview
- name: Setup nodejs
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: |
cd electron-example-browserview
npm install
- name: Package
run: |
cd electron-example-browserview
npx electron-builder --dir
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: package-${{ matrix.os }}
path: electron-example-browserview/dist/*
I tabulated the build times for the main steps. The average of two measurements (unit: seconds).
Linux x64 | Linux arm64 | |
---|---|---|
Setup nodejs | 8.5 | 5.0 |
Install dependencies | 10.0 | 5.5 |
Package | 24.0 | 23.5 |
Upload artifacts | 15.5 | 12.0 |
The time taken for packaging was almost equal, but there were differences in Node.js setup, npm install, and artifact upload, with the Arm version runner showing higher throughput overall.
Go Batch Processing
#This is a comparison of batch processing using sbgraph. It builds sbgraph, fetches page data from a Scrapbox project, and performs aggregation and graph structure generation. This was also run on both linux-x64
and linux-arm64
runners.
name: sbgraph benchmark
on:
workflow_dispatch:
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [linux-x64, linux-arm64]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 1.22
- name: Install sbgraph
run: |
go install github.com/mamezou-tech/sbgraph@latest
sbgraph init
sbgraph project -p help-jp
- name: Fetch data
run: sbgraph fetch
- name: Aggregate
run: sbgraph aggregate -s=true
- name: Generate Graph data
run: sbgraph graph -i=true -j=true
- name: Upload result
uses: actions/upload-artifact@v4
with:
name: help-jp-result-${{ matrix.os }}
path: _work/help-jp*
Here is the comparison of the main steps. The average of two measurements (unit: seconds). Setup Go and data fetch were slightly faster on x64, but Arm was significantly faster for go install, resulting in higher throughput overall for the Arm runner.
Linux x64 | Linux arm64 | |
---|---|---|
Setup Go | 4.0 | 7.5 |
Install | 35.5 | 19.5 |
Fetch data | 3.0 | 4.5 |
Aggregate | 0 | 0 |
Generate graph | 0 | 0 |
Upload | 1.5 | 1.0 |
Conclusion
#Although it was a simple benchmark, the Arm runner performed comparably to (and sometimes better than) the x64 runner. Given its lower cost, it makes sense to adopt the Arm runner as much as possible.
There are some software that do not run on the Arm architecture, so not all workflows can be replaced, but I intend to use it where applicable.
Arm-based Windows PCs were released quite some time ago, but they did not become popular, possibly due to lack of power or pricing issues. ↩︎