How to Make GitHub Actions 10x Faster
Most CI pipelines have 5-10x slack. We've audited dozens; the same five issues account for ~80% of the wasted time. Here's the pragmatic checklist.
1. Cache Everything That Can Be Cached
- uses: actions/cache@v4
with:
path: |
~/.npm
node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-node-
Standard, but most repos still don't cache ~/.cargo, ~/.gradle, ~/.m2, or pip wheels. Audit yours.
2. Parallelize Tests
The single biggest CI speedup most teams haven't done. Split your test suite into shards.
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v4
- run: pytest --shard ${{ matrix.shard }}/4
4 shards = ~4x speedup on test-heavy pipelines.
3. Docker Layer Caching
- uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/me/app:latest
cache-from: type=gha
cache-to: type=gha,mode=max
The type=gha cache uses GitHub's Actions cache backend. 5-10x speedup on rebuilds.
4. Self-Hosted Runners on Spot Instances
For high-volume teams, self-hosted runners on AWS Spot or Hetzner are 5-10x cheaper than GitHub-hosted. The actions-runner-controller for Kubernetes is mature in 2026.
5. Skip Unchanged Paths
on:
push:
paths:
- 'src/**'
- 'package.json'
- '.github/workflows/test.yml'
Don't run the full test suite when only docs changed. Path filters cost nothing to add.
FAQ
How much speedup is realistic?
3-5x is common. We've seen 10x on neglected pipelines. The work is usually 2-4 hours of audit and a day of implementation.
What's the order of operations?
Caching first (biggest ROI for least work). Then parallelization. Then Docker layer caching. Self-hosted runners last — only if you're hitting GitHub usage limits.
Have a correction or a different field experience? We update these pieces. Honest critique welcome.