The simplest way to reduce GitHub Actions costs without rewriting your workflows is to run the same jobs on GitHub Actions runners managed by Depot.
You keep the workflow triggers, jobs, steps, Marketplace actions, secrets, permissions, and pull request checks you already use. Connect your GitHub organization to Depot, then change one runner label:
jobs:
test:
- runs-on: ubuntu-24.04
+ runs-on: depot-ubuntu-24.04The runners are up to 3x faster than standard GitHub-hosted runners. They also include an in-memory disk accelerator and cache transfers up to 1000 MiB/s. Usage is tracked by the second with no one-minute minimum.
That matters because CI cost isn't just the advertised per-minute rate:
job cost = billable runtime x runner price
monthly compute cost = sum of every job costA cheap runner that takes twice as long can cost more. A faster runner at the same rate can cost less. Replacing the machine underneath the job lets you improve both sides of that equation without rebuilding the workflow.
Runtime usually matters more than the headline rate
As of September 9, 2026, a standard two-core Linux runner from GitHub and Depot both list a rate of $0.006 per minute. The billing behavior is different. GitHub rounds each job up to the next whole minute. Depot tracks usage by the second and calculates the total at the end of the billing period.
Consider 100 Linux jobs that each finish in 20 seconds:
| GitHub-hosted runner | Depot GitHub Actions runner | |
|---|---|---|
| Actual execution time | 2,000 seconds | 2,000 seconds |
| Billable time | 100 minutes | 33.33 minutes |
| Cost at $0.006/minute | $0.60 | $0.20 |
That's a 67% reduction before the faster runner or cache changes the execution time. The effect is largest for test matrices and other workflows with many short jobs.
Long jobs follow the same equation. If a 12-minute job finishes in four minutes on a runner with the same per-minute rate, its compute cost falls from $0.072 to $0.024. That example illustrates the math, not a promise that every job will run 3x faster.
Depot removes time from the existing job
Changing the runs-on label gives the workflow three ways to finish sooner.
- Faster compute. Depot Linux x64 runners use current-generation AMD EPYC CPUs, while Arm runners use AWS Graviton4. Linux and Windows sizes range from 2 to 64 vCPUs, so CPU and memory constrained jobs don't have to stay on one standard machine size.
- Faster disk. Linux and macOS runners reserve memory for a RAM-backed disk accelerator. Jobs that compile large codebases, install many dependencies, or create lots of small files spend less time waiting on disk I/O.
- Faster cache transfers. Depot automatically accelerates the cache used by
actions/cacheandactions/setup-*. You keep the same cache steps and keys. Uploads and downloads can reach 1000 MiB/s, up to 10x faster than the standard GitHub Actions cache.
The cache improvement is especially useful because a slow cache can erase its own benefit. If restoring an archive takes almost as long as rebuilding it, the workflow still pays for the transfer on every job. Faster restore and save times turn more of the existing cache configuration into actual runtime savings.
Use the cheapest runner for the completed job
The smallest runner doesn't always produce the lowest bill.
An eight-core runner costs more per minute than a two-core runner. It's cheaper overall only when the extra compute reduces runtime enough to cover that price difference. Use this break-even test:
new runtime / old runtime < old runner price / new runner priceFor example, moving from a two-core Depot Linux runner at $0.006 per minute to an eight-core runner at $0.024 per minute raises the rate by 4x. The job must run more than 4x faster to reduce compute cost. If it runs 3x faster, you paid more for a faster result. That may still be worth it for feedback time, but it isn't a cost reduction.
Depot's GitHub Actions analytics show CPU, memory, and step-level timing data. Use those metrics to find jobs that are constrained by the runner before increasing its size. Use step timing and logs to investigate disk or network bottlenecks. More CPU won't fix a job that spends most of its time waiting on an external API.
Include the cost of operating self-hosted runners
Running your own virtual machines can make the provider invoice look smaller. It also moves costs into engineering.
A production runner fleet needs capacity planning, autoscaling, base image updates, security patches, job isolation, cache storage, metrics, failed-machine cleanup, and incident response. Idle capacity costs money. So does the time a platform engineer spends keeping the fleet alive.
Use the full equation when comparing managed and self-hosted runners:
total runner cost = compute + storage + network + idle capacity + engineering timeDepot starts a fresh, single-tenant virtual machine for every job and destroys it when the job completes. There's no idle fleet for your team to size or patch. If policy requires the runners to execute inside your AWS account, Depot can also run its managed runner infrastructure there.
Cases where the invoice may not fall
Depot isn't automatically cheaper for every repository or every job.
- Standard GitHub-hosted runners are free for public repositories. Moving a public project for cost savings alone doesn't make sense.
- If your organization stays inside its included GitHub Actions allowance, faster jobs may improve feedback time without reducing the current invoice.
- A job bottlenecked on an external service may not get faster from better compute, disk, or caching.
- Per-minute prices vary by operating system and runner size. Compare the current rates and the completed-job cost, not a generic percentage claim.
- Depot GitHub Actions runners require a repository owned by a GitHub organization. Repositories owned by personal accounts aren't supported.
- Depot Windows runners don't support Hyper-V. Windows jobs that require Hyper-V or Docker on Windows need a different execution environment.
Roll out the change one job at a time
Start with the jobs consuming the most billable time, not the workflow with the most YAML.
- Record the current p50 and p95 runtime, billable minutes, queue time, and cache restore time for the job.
- Change its
runs-onlabel to the equivalent Depot GitHub Actions runner type. - Run enough normal pull requests to include warm caches, cold caches, and a representative test load.
- Compare completed-job cost using runtime multiplied by the runner rate.
- Keep the new label where it wins. Try another runner size when the metrics show a CPU or memory constraint.
You can migrate one job, one workflow, or one repository at a time. The rest of GitHub Actions keeps working exactly as it did before.