Runners
4 min read

GitHub Actions vs BuildPulse runners, benchmarked

Real workloads, pinned versions, public runs you can fork and rerun: the same jobs finish 1.4 to 1.9x sooner and cost 52 to 65 percent less blended. Every number links to a run.

BuildPulse Team

August 15, 2026

GitHub Actions vs BuildPulse benchmark: 48 percent less docker build time, 65 percent less blended cost, 171 percent more CPU throughput

Every managed runner's homepage says faster. Saying it is easy. We moved our own repos to our own runners and then measured it in public, on real workloads, with a repo you can fork and rerun. Claims are marketing; runs are receipts. Here are the receipts.

Everything below comes from github.com/buildpulse/runner-benchmarks: pinned versions of real open-source projects, identical jobs on both runners, medians over repeated runs. If you get different numbers, let us know by opening an issue.

Speed, measured

Both runners at 4 vCPU. Medians:

WorkloadGitHub ubuntu-latestBuildPulse x64-4xTime saved
Docker image build (hugo's own Dockerfile, no cache)243s126s48%
Node install + build + tests (vuejs/core, pinned)92s54s41%
Go compile (hugo, pinned)67s46s31%

Speed comparison: three workloads, GitHub vs BuildPulse

The pattern: the more compute-bound real work your job does (docker builds, dependency installs, test suites), the bigger the gap. A newer AMD EPYC generation is most of the story. That claim is measurable too, so we measured it.

The hardware, measured

Same sysbench and fio commands on both runners, straight from the hardware workflow:

ProbeGitHub ubuntu-latestBuildPulse x64-4xDifference
CPUAMD EPYC 7763 (Zen 3, 2021)AMD EPYC 9R45 (Zen 5, 2025)2 generations
sysbench CPU (events/s, all cores)8,18622,178+171%
sysbench memory throughput12.0 GB/s27.8 GB/s+133%

Zen 5 is the newest server generation AMD makes; GitHub's fleet is two generations behind it. Same sysbench commands on both machines. The full probe set, including disk, is in the public workflow logs; run it yourself on any runner.

The cache your next build actually hits

Cold-vs-warm is where runner infrastructure differences stop being subtle. The docker-cache workflow builds hugo's Dockerfile twice, and the warm build runs on a fresh machine, so any difference between cold and warm comes from the cache infrastructure and nothing else. The GitHub side uses GitHub's own recommended caching for docker builds. On BuildPulse there is nothing to set up: docker-builder machines keep each customer's layer cache between builds, so your second build is fast without a single line of cache configuration in the workflow.

Cold buildWarm rebuild, fresh machine
GitHub + gha cache276s3s
BuildPulse docker-builder145s1s

There are two takeaways. Cold builds finish in half the time, same pattern as everything above. Warm rebuilds of this image are near-instant on both: hugo's layer cache is small enough that GitHub's remote cache restores it fine. The differences that matter show up in what surrounds that number.

  • Zero configuration. No cache-from, no cache-to, no scope keys in your workflow.
  • No 10 GB per-repo cache quota, no eviction fighting other caches in the repo.
  • Package-manager caches inside the build (RUN --mount=type=cache) survive between builds, because the cache is the build machine's own storage. Remote cache backends drop these.

Cost, blended

Per-minute rates are 20 to 50 percent below GitHub's (4 vCPU: $0.008/min vs $0.012). But the per-minute rate is the small half: you also buy fewer minutes, because the same job finishes in 31 to 48 percent less time. Blended:

The same workload costs 54 to 65 percent less.

In dollars: every $100 of docker builds on GitHub Actions costs about $35 here (65% saved); node builds $39 (61% saved); Go compiles $46 (54% saved).

Every 100 dollars of GitHub Actions, priced on BuildPulse

The full rate table is on buildpulse.io/pricing.

Why BuildPulse

The same jobs finish in 31 to 48 percent less time, on CPUs two generations newer, with a docker cache that works without configuration. In practice: a $1,000 a month GitHub Actions bill becomes roughly $350 to $460 for the same workloads, or the same budget runs two to three times the CI. You do not have to take our word for any of this: every number above links to a public run, and the harness is a repo you can fork and point at your own workloads.

Then there is the part no benchmark table shows, and the reason we built runners at all: every job on BuildPulse runners feeds the same platform's flaky-test detection. A red build tells you whether the failure is your code or a test with a known failure history before an engineer spends twenty minutes finding out manually. Faster minutes are table stakes; knowing which failures matter is the product.

Migrate in one line

 jobs:
   test:
-    runs-on: ubuntu-latest
+    runs-on: bp-ubuntu-latest-x64-4x

That is the entire change for most workflows. A few workflows also need a setup action for tools our deliberately minimal image does not preinstall (in our own migration of thirteen repos, exactly three: composer, sbt, and Chrome). The full step-by-step guide is its own post.

Runners that know whether the failure is your code or a flaky test. Try BuildPulse

Stop guessing which tests you can trust

BuildPulse finds your flaky tests, ranks them by the engineering time they cost, and lets you quarantine the worst in one click. See results on your first build.

Free to start · No credit card required · Setup is a single CI step