Last week I was deploying our Lingo.dev app as a Docker image from a GitHub Action. And to deploy it, I had to build it inside on a Github-hosted runner. However I hit the limit:
"You are running out of disk space."
Have you ever hit this sudden and mysterious failure in your GitHub Actions workflow too?
As our CI pipelines grew in complexity and size, we run out of disk space on GitHub-hosted runners. In this practical guide, I’ll show you what fills up the disk, how I analyzed it, and what I did to reclaim enough space to make my builds reliable again.
💡 tl;dr go to chapter 6 and copy the Github Action step to clean up your Github-hosted runner.
1. The Limits of GitHub-hosted Runners
GitHub-hosted runners come preloaded with a wide variety of programming languages, SDKs, and tools. This is great for convenience, but the trade-off is bloat. Here's what a typical ubuntu-latest
runner includes:
- Preinstalled languages: Java (multiple JDKs), .NET, Python, Ruby, Go, Swift, Haskell (GHC), Julia, Node.js
- Developer tools: Android SDK, Docker, Azure CLI, Google Cloud SDK, CodeQL, browsers (Chrome, Edge, Firefox), Chromium
- Miscellaneous: PowerShell, Rust toolchains, LLVM, debugging tools
Out of ~72 GB total disk, over 50 GB is used before any workflow step runs.
2. Hitting the Wall: My Symptoms
I was building and deploying Docker images using a GitHub Actions workflow. Everything worked fine until the job suddenly failed with a disk space error during the Docker build phase.
You are running out of disk space. The runner will stop working when the machine runs out of disk space. Free space left: 54 MB
This prompted me to figure out what was actually eating up all the space.
3. Measuring the Beast: How Much is Used and Where 🤔
To understand the problem, I added the following steps to the GitHub Actions workflow:
- name: Show disk usage
run: df -h
- name: Top-level directories
run: du -h -d1 / | sort -hr | head -n 20
- name: Detailed file sizes
run: find / -type f -exec du -h {} + 2>/dev/null | sort -hr | head -n 1000
Here's what I found:
-
/usr
: 34 GB — this directory holds most system software and preinstalled runtimes like Java, Swift, and .NET. It's often the largest. -
/opt
: 11 GB — contains hosted toolcaches for things like CodeQL, Go, and language-specific tools that GitHub Actions preinstalls. -
/mnt
: 4.1 GB — usually used for temporary mounts or ephemeral files. Sometimes includes scratch space used during builds. -
/home
: 1.2 GB — stores user-level data, including runner-specific config, caches, and things like rustup toolchains.
Looking closer, it was clear that /usr/share/swift
, /usr/local/.ghcup
, and /usr/local/lib/android
were some of the biggest space hogs.
4. What's Hiding in Your Runners?
Most of the disk was taken up by things I didn’t need. Here's a breakdown:
Languages and Runtimes
Tool | Path | Approx Size |
---|---|---|
Java | /usr/lib/jvm |
~1.5 GB |
.NET | /usr/share/dotnet |
~1.5 GB |
Swift | /usr/share/swift |
~2.5 GB |
Haskell | /usr/local/.ghcup |
~3 GB |
Rust | /home/runner/.rustup |
~1.5 GB |
Julia | /usr/local/julia* |
~500 MB |
Android SDK | /usr/local/lib/android/sdk |
~6 GB |
Browsers |
/usr/local/share/chromium , etc. |
~1.5 GB |
Developer Tools
Tool | Path | Approx Size |
---|---|---|
CodeQL | /opt/hostedtoolcache/CodeQL |
~2 GB |
PowerShell | /usr/local/share/powershell |
~800 MB |
Azure CLI | /opt/az |
~200 MB |
Google SDK | /usr/lib/google-cloud-sdk |
~200 MB |
5. What Can You Safely Remove? 🗑️
Depending on your use case, you can remove different tools. Since I was building and deploying Docker images for a Node.js application, I didn’t need most preinstalled SDKs and languages.
Here are a few examples:
- Node.js project: remove Java, .NET, Swift, Haskell, Android SDK, CodeQL
- Python scripts: remove Java, .NET, Android, Browsers
- Java application: remove Swift, Haskell, CodeQL, Node.js, Android SDK
In general, you can also remove browsers like Chromium if you’re not using them for end-to-end testing.
6. How to Automate Cleanup in Your CI 🚮
I added this step to the top of my GitHub Actions workflow:
- name: Aggressive cleanup
run: |
# Remove Java (JDKs)
sudo rm -rf /usr/lib/jvm
# Remove .NET SDKs
sudo rm -rf /usr/share/dotnet
# Remove Swift toolchain
sudo rm -rf /usr/share/swift
# Remove Haskell (GHC)
sudo rm -rf /usr/local/.ghcup
# Remove Julia
sudo rm -rf /usr/local/julia*
# Remove Android SDKs
sudo rm -rf /usr/local/lib/android
# Remove Chromium (optional if not using for browser tests)
sudo rm -rf /usr/local/share/chromium
# Remove Microsoft/Edge and Google Chrome builds
sudo rm -rf /opt/microsoft /opt/google
# Remove Azure CLI
sudo rm -rf /opt/az
# Remove PowerShell
sudo rm -rf /usr/local/share/powershell
# Remove CodeQL and other toolcaches
sudo rm -rf /opt/hostedtoolcache
docker system prune -af || true
docker builder prune -af || true
df -h
This alone saved more than 20 GB of space.
7. Bonus: Logging & Debugging Disk Usage Over Time 📊
To keep an eye on disk usage trends or debug failures, I uploaded disk logs as artifacts:
- name: Upload disk logs
uses: actions/upload-artifact@v3
with:
name: disk-logs
path: logs/
I generate the logs using tools like df
, du
, and find
, and use them for future audits.
8. Final thoughts
Disk space can quietly break your CI/CD pipelines. GitHub-hosted runners are filled with helpful tools, but many are unnecessary for your project. By auditing and removing what's not needed, I was able to consistently reclaim 15–25 GB of space and run Docker builds reliably.
Feel free to use the Aggressive cleanup step (see above) in your own Github Action.
If you're running into disk issues, don’t jump to larger runners. Start by cleaning up what you don’t use.
Let me know on X @mathio28 if you had a similar issue.
Images:
- Photo by Bruce Hong on Unsplash
- Photo by Roman Synkevych on Unsplash
Top comments (6)
Excellent article, Matej 😁👍
Not many developers know about this problem, but it's pretty annoying.
Great article!
Thanks! I agree, its a hidden pain. I hope this helps many engineers who run into the same issue.
honestly this is the kind of fix i needed ages ago - been cool seeing steady progress, so you think most devops problems end up just being about knowing what to throw away?
Yes, it looks like in this case it was. I am happy my article helped 🎉
I dont know about other problems - I would not call myself devops expert nor devops engineer though, far from it. Just an enthusiast and end-user many CI/CD tools 🙃
Great article!
And I love the name of your workflow. "Aggressive cleanup" - strong !