---
title: "10x faster arm64 builds on Github Actions"
description: "A simple one-liner mix of Github's managed runners for x86 and a self-hosted runner for arm64."
datePublished: 2022-12-02T11:05:00.000Z
slug: "gha-arm"
previewImage: "/preview/gha-arm64.png"
permalink: "https://obviy.us/blog/gha-arm/"
---

> **Update, September 2026:** GitHub now offers hosted arm64 runners. My [2025 multi-arch build guide](https://obviy.us/blog/fastest-gha-multi-arch-docker/) uses them without a self-hosted machine. The setup below records how I solved this in 2022.

`@SuperSeriousBot` is my playground. When I experiment with anything new, I use it as a testbed of sorts. It has served me well (over 4 years!) and is in a state of constant flux.

The latest addition to the Frankenstein’s monster that is `@SuperSeriousBot`, is `arm64` builds of the base Docker image.

However…

![Screenshot of extremely long CI builds](https://obviy.us/_astro/slow-ssgbot-builds.k2pbW9_M_Z1rFkTy.webp)

Snooze…

These build times are despite extremely aggressive artifact caching (almost 1.2GB in size now). Since Github (as of 2022) offers only x86 runners for Actions, the `arm64` images need to be built via QEMU emulation, leading to these long waits. Something needed to be done. I pushed a change to the repo and got down to work.

## Appending Buildx Nodes

I’ve already been using `buildx` for all my Docker needs. I found this gem of an action called [`baschny/append-buildx-action`](https://github.com/baschny/append-buildx-action) which will append a `buildx` node to an already setup action.

It does this by SSH-ing into a self-hosted runner and running the `docker buildx create` command. All it needs is the IP address of the self-hosted runner and the private key to SSH into it.

It was so painless that all I needed to do was provide the machine and add the following lines to my workflow:

```yaml
- name: "Append ARM buildx builder"
  uses: baschny/append-buildx-action@v1
  with:
    builder: ${{ steps.builder.outputs.name }}
    endpoint: "ssh://ubuntu@${{ secrets.SSH_HOST }}"
    ssh_private_key: ${{ secrets.ARM64_RUNNER_SSH_PRIVATE_KEY }}
```

I was able to get this working before the last change had even finished building!

## Results

![Screenshot of extremely short CI builds](https://obviy.us/_astro/fast-ssgbot-builds.EaeX0wWq_9d5bo.webp)

_Blazingly_ fast

Very nearly a 10x improvement.

À bientôt!
