Benchmark: Next.js builds 142x faster on Avrea than GitHub Actions
On GitHub Actions, a no-cache Next.js build takes 3 minutes 23 seconds. On Avrea, the same build, same 2 vCPU spec: 1 minute 23 seconds without cache, 1.4 seconds with a warm Turborepo cache.

Why Next.js
Next.js is a widely-deployed JS framework, and its monorepo uses Turborepo for build caching. That makes it a useful proxy for any JavaScript monorepo using task-output caching: Turborepo, Nx, Moon, or similar.
Task-output caching is straightforward: hash the task's inputs, look up the output, and if the output is there, skip the work. When most inputs match, a warm build is mostly cache reads.
How we ran the test
We ran Next.js's standard Turborepo build on both sides. Node LTS, 2 vCPU runners, pinned Next.js commit.
| GitHub Actions | Avrea | |
|---|---|---|
| Runner label | ubuntu-24.04 | avrea-ubuntu-latest-2-vcpu |
| vCPU | 2 | 2 |
| RAM | 7.8Gi | 7.8Gi |
For the cached run, Turborepo's remote cache pointed at Avrea's cache backing. On the no-cache run, Turborepo ran with caching disabled entirely. The GitHub Actions side had no remote cache on either run.
Three runs per configuration. The Avrea cached builds were boringly consistent (1.4 seconds each, plus or minus a fraction). No-cache runs had a few seconds of jitter.
Results
| GitHub Actions | Avrea | Speedup | |
|---|---|---|---|
| No cache | 3m 23s | 1m 23s | 2.4x |
| With cache | n/a | 1.4s | 142x |
Hardware alone runs 2.4x faster. Adding Turborepo's remote cache against Avrea's cache layer collapses the warm build to 1.4 seconds. Turborepo against GitHub's runners has no comparable cache path in this test.
Why it's faster
The hardware (the 2.4x)
A no-cache Next.js build is bundling-heavy: swc, esbuild, Next's compiler, and a fair amount of disk churn for intermediate artifacts. Avrea's single-core CPU advantage and NVMe disk carry most of the 2.4x.
The cache (the 142x)
Turborepo hashes each task's inputs (source files, config, dependencies). On a cached run with all inputs matching, the build becomes a series of cache reads and not much else.
Avrea's cache backing is on-runner. At NVMe read speeds, a Next.js build with all tasks cached takes 1.4 seconds because that's roughly how long it takes to read the task outputs back and verify them. Most of those 1.4 seconds is pnpm resolving the workspace plus Node booting. The bundler does close to nothing.
When every task in the graph is a hash hit, what the build actually does is pnpm resolving, Node booting, and Turborepo walking the graph. No bundling, no compilation. 142x is what that looks like in a number.
Other benchmarks in this series
- Bazel (39.7x)
- Linux kernel (68x)
- Ghostty (27x)
- Kafka (6.6x)
- RisingWave (11.5x)
What Avrea is
Avrea swaps in for GitHub Actions runners with one line of YAML. Change runs-on: ubuntu-latest to runs-on: avrea-ubuntu-latest.
You get per-step CPU and memory, a searchable log history, and SSH access to running jobs. On Turborepo specifically, the SSH access saves you time when a task hangs deep in the build graph. Inspecting in place is faster than killing the run and starting cold.






