Reducing GitHub Actions Costs
Practical guide to reducing GitHub Actions costs with triggers, cancellation, caching, right-sizing, and more

This guide focuses on practical ways to reduce costs while improving reliability and developer UX. It's vendor-neutral and cites primary docs throughout.
Note
Cost is largely a function of billed minutes, runner SKU, artifact/storage usage, and fan-out. Understanding billing and usage is the first step: see About billing for GitHub Actions and Viewing your Actions usage.
Cost Optimizations
Run less by default (event filters)
Only run workflows when it matters.
on:
pull_request:
branches: ["main", "release/*"]
paths: ["app/**", "lib/**", "package.json"]
paths-ignore: ["**/*.md", "docs/**", "*.png", "*.svg"]
push:
branches: ["main"]
- See workflow syntax for
paths
/paths-ignore
: docs - Skip runs with commit messages or workflow inputs: skipping runs
Tip
Use separate lightweight linters for every push and run heavy integration tests only for PRs targeting main
.
Cancel superseded work
Stop old runs when new commits arrive.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
- Concurrency groups and cancellation: docs
Add timeouts to jobs
Set hard ceilings on job time.
jobs:
test:
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm test
- Timeouts via workflow syntax: docs
Cache smartly (dependencies and Docker)
Caching cuts both time and cost.
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: npm-${{ runner.os }}-
- Dependency caching: docs
For Docker image builds, prefer BuildKit/Buildx with the GitHub cache backend:
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v5
with:
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
- Buildx cache with
type=gha
: Docker docs
Store less, keep it shorter (artifacts)
Artifacts are billed for storage and egress. Upload only what you need, compress appropriately, and reduce retention.
Example savings: A team uploading 5GB of artifacts daily with default 90-day retention stores 450GB/month. Reducing retention to 7 days cuts this to 35GB-a 92% reduction. At GitHub's storage rates ($0.008/GB/day for Actions), this saves ~$100/month.
- uses: actions/upload-artifact@v4
with:
name: reports
path: reports/**
retention-days: 7 # default is 90 days
compression-level: 6 # balance speed vs size
Quick wins:
-
Reduce retention from 90 to 7-14 days: ~85-90% storage cost reduction
-
Compress artifacts: typical 40-60% size reduction for logs and build outputs
-
Upload only test failures, not full test runs
-
Artifacts and retention: docs
Choose cheaper runners and architectures
Linux runners are cheaper than macOS/Windows. Where possible, move tasks to Linux, and isolate platform-specific steps. Use arm64 runners for builds that are not CPU bound.
GitHub-hosted pricing multipliers (relative to Linux x64):
- Linux x64: 1x baseline
- Linux arm64: ~0.5x (50% cheaper)
- Windows: 2x (2x more expensive)
- macOS x64: 10x (10x more expensive)
- macOS arm64 (M1): 3-5x (3-5x more expensive)
Example: A workflow running 1,000 minutes/month on macOS x64 costs ~10x more than the same workflow on Linux. Switching non-macOS-specific tasks to Linux can save $80-90/month per 1,000 minutes at typical GitHub Teams pricing.
Note
Billing differences and entitlements vary by plan and OS: see About billing for GitHub Actions.
Parallelize thoughtfully
Matrix builds are powerful but can explode costs. Keep fan-out intentional and throttle when needed.
strategy:
matrix:
node: [18, 20, 22]
max-parallel: 2
- Matrix usage and limits (256 jobs): docs
Observe and budget
Track performance and spend so you can right-size and de-fanout with confidence.
Right-size your runners
Use data to pick the smallest runner that meets SLOs.
Example: If a build takes 20 minutes on 2-core and 12 minutes on 8-core, you're paying 4x the rate for a 1.67x speedup-net result is 2.4x more expensive for that run. Right-sizing down from 8-core to 4-core (if 4-core completes in 15 minutes) cuts cost by 2x while only adding 3 minutes. This optimizes for cost but developer experience may suffer.
- Track job duration trends in the Actions UI and compare before/after changes: usage
- Watch CPU/memory-bound steps: run smaller/larger machine experiments and choose the knee of the curve
- Prefer improving IO (cache, network, disk) before simply scaling CPU
Mermaid decision helper:
Tip
To test right-sizing safely, cap max-parallel
, then A/B compare durations and queue times before switching your default runner.
Flaky tests quietly tax your bill
Retries and re-runs multiply minutes. Treat flakiness as a cost center.
- Prefer “retry failed tests only” where supported (keeps cost bounded)
- Quarantine known-flaky suites and run them on schedule, not per-PR
- Surface failure triage early; fail fast before long e2e suites
Framework knobs (examples):
See: jest.retryTimes
# Jest
run: npx jest --maxWorkers=50% # consider also: jest.retryTimes()
# Playwright config
use:
retries: 2
workers: 4
See: pytest-rerunfailures
# Pytest example
pytest -q --maxfail=1 # fail fast
pytest --reruns 2 --only-rerun "AssertionError"
- Re-running jobs/workflows: docs
Self-hosted runners can save costs
Self-hosting can reduce per-minute costs (e.g., spot/preemptible instances) and unlock bespoke hardware and caching. It also introduces infra, security, and maintenance overhead.
Optimizing Self-Hosted GitHub Actions Runner Costs
Compared to GitHub hosted runners, self-hosted runners have the potential to save upto 90% on costs.
Cost-first execution flowchart
How WarpBuild can help
This guide is vendor-neutral; if you want managed building blocks that implement many of the above:
- Fast cloud runners (Linux, Windows, macOS):
https://docs.warpbuild.com/ci/cloud-runners/
- Snapshot runners:
https://docs.warpbuild.com/ci/snapshot-runners/
- Fast cache and Docker Builders:
https://docs.warpbuild.com/ci/cache/
,https://docs.warpbuild.com/ci/docker-builders/
- Observability guides:
https://docs.warpbuild.com/ci/observability/
- Quick start:
https://docs.warpbuild.com/ci/quick-start/
Last updated on
Optimizing Self-Hosted GitHub Actions Runner Costs
Checklist of strategies to cut self-hosted GitHub Actions costs with networking, caching, autoscaling, and compliance-friendly patterns.
Blacksmith vs WarpBuild Comparison - 2025 May
Blacksmith features, performance, pricing, and how it compares to WarpBuild.