Mastering Disk Space on GitHub Actions Runners: A Deep Dive into Cleanup Strategies for x64 and arm64 Runners

If you’ve ever hit that dreaded No space left on device error mid-build in your GitHub Actions workflow, you’re not alone. GitHub Actions is a powerhouse for CI/CD, but the hosted runners it uses come with finite resources—especially disk space. As your projects grow (think massive Docker builds, hefty node_modules, or sprawling test suites), that space can evaporate faster than a bad pull request.

In this post, we’ll unpack the disk space landscape for GitHub-hosted runners, including the rising star of arm64 options. We’ll break down what’s hogging your storage, and arm you with a battle-tested script to reclaim precious GBs right in your workflow YAML. By the end, you’ll be optimizing like a pro, keeping your pipelines humming without upgrading to larger runners or self-hosting (though we’ll touch on when those make sense).

Let’s roll up our sleeves and dive in.

Table of Contents

Understanding Disk Space on GitHub-Hosted Runners

GitHub’s hosted runners are virtual machines spun up on demand, pre-loaded with a treasure trove of tools (Node.js, Python, Java, Docker—you name it). But they’re not infinite. According to the official GitHub-hosted runners reference, Linux runners (the go-to for most workflows via ubuntu-latest) ship with 14 GB of SSD disk space. This is the usable ephemeral storage allocated for your job—enough for small-to-medium builds, but tight for anything involving large artifacts or layered Docker images.

In practice, the underlying filesystem is much beefier, clocking in at around 72 GB total. Fresh runners start with about 22 GB free for x64 and 45 GB free for arm64, but that shrinks as your workflow downloads dependencies, caches layers, or installs SDKs. Windows and macOS runners have similar constraints, but we’ll focus on Linux since it’s the most common.

Spotlight on arm64 Runners: Efficiency Meets Constraints

If you’re building for modern ARM-based environments—like AWS Graviton, Apple Silicon, or edge devices—GitHub’s arm64 runners are a game-changer. Launched in public preview in early 2025 and now generally available, these runners (labeled ubuntu-24.04-arm or ubuntu-22.04-arm for Linux) deliver native arm64 execution, slashing build times (e.g., from 30+ minutes to ~4 minutes) and cutting costs by 37% compared to equivalent x64 runners by avoiding emulation overhead. They’re free for public repos and available on Team/Enterprise plans for private repos, with the same documented 14 GB usable disk space as their x64 counterparts—ensuring parity in storage limits but with sustainability perks like 30-40% lower power use.

All GitHub-provided actions are compatible, though you’ll want ARM-native dependencies to avoid cross-compilation hiccups.

Pro tip: Use runs-on: ubuntu-latest-arm64 (alias for the latest stable) to future-proof.

Why the discrepancy in docs? GitHub emphasizes guaranteed usable space for jobs, while the full VM has overhead for the OS, pre-installed tools, and runner internals. If you’re seeing warnings like You are running out of disk space. Free space left: 54 MB, it’s time to audit and act—regardless of architecture.

Quick Tip: Monitor Your Space

Add this to any workflow for a snapshot:

- name: Check Disk Usage
  run: |
    df -h /
    du -sh /* 2>/dev/null | sort -hr | head -10
    uname -m  # Bonus: Confirms x64 vs. aarch64

This’ll reveal the top space hogs at a glance, plus architecture for ARM verification.

x64 runner disk usage:
Run df -h /
  df -h /
  du -sh /* 2>/dev/null | sort -hr | head -10
  uname -m  # Bonus: Confirms x64 vs. aarch64
  shell: /usr/bin/bash -e {0}
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        72G   50G   22G  70% /
38G		/usr
8.5G	/opt
4.1G	/mnt
1.6G	/home
690M	/etc
492M	/var
62M		/boot
1.2M	/run
784K	/imagegeneration
84K		/dev
x86_64
arm64 runner disk usage:
Run df -h /
  df -h /
  du -sh /* 2>/dev/null | sort -hr | head -10
  uname -m  # Bonus: Confirms x64 vs. aarch64
  shell: /usr/bin/bash -e {0}
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        72G   27G   46G  38% /
19G		/usr
3.1G	/swapfile
2.2G	/opt
1.7G	/home
605M	/etc
546M	/var
61M		/boot
1.1M	/run
772K	/imagegeneration
100K	/dev
aarch64

What’s Eating Your Disk? A Breakdown of Runner Filesystem Usage

GitHub runners boot from a standardized image (check the actions/runner-images repo for x64; arm64 uses actions/partner-runner-images), so the filesystem is predictable. The workspace for your repo lives under /home/runner/work/<repo>, but the real culprits are system-wide installs and caches.

To get granular, I simulated a fresh ubuntu-latest (x64) and ubuntu-latest-arm64 runner and ran du -h -d1 / | sort -hr. Here’s a typical breakdown (your mileage may vary slightly based on the image version; arm64 tends to be leaner due to native binaries):

Directory/PathTypical Size (x64)Typical Size (arm64)What’s Inside?
/usr/lib/jvmN/A1.5 GBJava JDK
/usr/local/.ghcup6.4 GBN/AHaskell compiler installer
/usr/local/lib/android9.5 GBN/AAndroid SDK/NDK
/usr/local/share/powershellN/A1.3 GBPowershell SDKs
/usr/share/dotnet3.4 GB3.6 GB.NET runtimes and SDKs
/usr/share/swift3.2 GB3.2 GBSwift runtime and SDKs
/opt/hostedtoolcache6 GBN/APre-cached tools (Node, Python, Go, Ruby, .NET SDKs, etc.)
Potential space savings28.5 GB9.6 GB

Reclaiming Space: A GitHub Actions Cleanup Script

The beauty of GitHub Actions? You can script cleanups within your workflow. No need for self-hosted runners (yet)—just add a step early on to prune the fat. This works identically on x64 and arm64 Linux runners, as the paths and commands are OS-agnostic. You can use custom actions like jlumbroso/free-disk-space but even removing targeted directories yourself is easy and can quickly give you 5-10 GB of free space.

The GHA workflow YAML script

GitHub Action step to clean runner
      - name: Clean Up Disk Space
        if: runner.os == 'Linux'
        run: |
          # Space usage before cleanup
          df -h /

          # Remove unused tool caches (comment any required ones with #)
          sudo rm -rf /usr/lib/jvm
          sudo rm -rf /usr/local/.ghcup
          sudo rm -rf /usr/local/lib/android
          sudo rm -rf /usr/local/share/powershell
          sudo rm -rf /usr/share/dotnet
          sudo rm -rf /usr/share/swift
          sudo rm -rf "$AGENT_TOOLSDIRECTORY"
 
          # Verify gains
          df -h /

Results

x64 runner (53 GB usable space)
Run # Space usage before cleanup
  # Space usage before cleanup
  df -h /
  
  # Remove unused tool caches (comment any required ones with #)
  sudo rm -rf /usr/lib/jvm
  sudo rm -rf /usr/local/.ghcup
  sudo rm -rf /usr/local/lib/android
  sudo rm -rf /usr/local/share/powershell
  sudo rm -rf /usr/share/dotnet
  sudo rm -rf /usr/share/swift
  sudo rm -rf "$AGENT_TOOLSDIRECTORY"
  
  # Verify gains
  df -h /
  shell: /usr/bin/bash -e {0}
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        72G   50G   22G  70% /
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        72G   20G   53G  27% /
arm64 runner (55 GB usable space)
Run # Space usage before cleanup
  # Space usage before cleanup
  df -h /
  
  # Remove unused tool caches (comment any required ones with #)
  sudo rm -rf /usr/lib/jvm
  sudo rm -rf /usr/local/.ghcup
  sudo rm -rf /usr/local/lib/android
  sudo rm -rf /usr/local/share/powershell
  sudo rm -rf /usr/share/dotnet
  sudo rm -rf /usr/share/swift
  sudo rm -rf "$AGENT_TOOLSDIRECTORY"
  
  # Verify gains
  df -h /
  shell: /usr/bin/bash -e {0}
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        72G   27G   46G  38% /
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        72G   18G   55G  25% /

Happy cleaning! 🧹

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top