Using High Cost-Performance and Power-Efficient Arm-Based GitHub Actions Runner

| 6 min read
Author: masahiro-kondo masahiro-kondoの画像
Information

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.

Manage runners

Click New GitHub-hosted runner.

New GitHub-hosted runner

The UI for creating a runner will be displayed. Linux ARM64 and Windows ARM64 can be selected as Beta.

Create new runner

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.

Create Linux Arm64 Runner

The runner was set up and available immediately.

Linux Arm64 Runner created

Speed Comparison

#

In addition to the above Arm Runner, I created a minimum configuration x64 Runner named linux-x64 for comparison.

Linux-x64 runner

Information

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.

build-electron-app.yml
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.

bench.yml
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.


  1. 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. ↩︎

豆蔵では共に高め合う仲間を募集しています!

recruit

具体的な採用情報はこちらからご覧いただけます。