Skip to content
vxvx
GitHubBlueskydev.toRSS
Blog

Benchmarks you can re-run

One synthetic task graph, each tool in its own native config, every number one command away.

Every number on our benchmark page is one command away. Here is the time each runner adds on top of the tasks, on one 9,603-task graph:

Cold build overhead
vx6.68 s
Turborepo11.18 s
Nx3 min 12 s
Vite Task8.51 s
Nothing changed
vx559 ms
Turborepo689 ms
Nx12.07 s
Vite Task10.71 s
Cold build CPU
vx42.19 s
Turborepo1 min 19 s
Nx5 min 31 s
Vite Task24.17 s
The table
Runner Cold build overhead Nothing changed Cold build CPU
vx 6.68 s 559 ms 42.19 s
Turborepo 11.18 s 689 ms 1 min 19 s
Nx 3 min 12 s 12.07 s 5 min 31 s
Vite Task 8.51 s 10.71 s 24.17 s

Synthetic monorepo, 1,601 projects, 9,603 tasks, 30 levels · build 300 ms, test and typecheck 150 ms, lint 75 ms, publish 30 ms · concurrency 10

Measured: vx 0.0.0 @ ee4c63a57 on 2026-11-12, Turborepo 2.11.10 on 2026-11-12, Nx 24.0.2 on 2026-11-12, Vite Task 1.4.0 on 2026-11-12; linux x64, 4 cores (AMD EPYC 7763 64-Core Processor), 16 GB.

Lower is better. A cold build’s tasks alone take 1 min 53 s with an ideal schedule. With nothing changed the ideal is 0, so all of that time is the runner.

The table is filled from the latest run when the site is built: each change to vx re-measures vx, and a new Turborepo, Nx or Vite Task pin re-measures that tool.

Terminal window
$ bun private/vx-bench/compare.ts 3

Every task is a sleep of a fixed length, so the numbers measure the runner, not a compiler. Each runner runs the graph cold, with nothing changed, and with outputs restored.

The site takes its rows from vx run @vzn/vx-bench#site.numbers: one task per runner, each on a machine of its own.

Rule Why
each tool in its native config Turborepo turbo.json, Nx nx:run-commands targets, Vite Task vite.config.ts
concurrency 10 for all same parallelism
vx as the compiled binary, from a vx lock snapshot what users install and CI runs
CI mode as CI runs them
one runner at a time no daemon idle-contends for CPU
no edit row Nx needs its daemon for one, and CI doesn’t run it

Turbo and Nx run as they would in CI (CI=1: Nx’s daemon off, and Turbo uses none for turbo run).

The first two columns are wall time. The third is the runner’s own CPU time, minus the tasks. A daemon that outlives the run isn’t counted, so Turborepo’s and Nx’s CPU are lower bounds.

Every row is on Benchmarks.

Every change to vx’s warm path ships with a number measured like this: before and after interleaved, fastest of N, “before” built from its own git worktree.

If a number here doesn’t reproduce on your machine, please file a bug.

More at vznjs.github.io/vx.

Turborepo, Nx and other product names are trademarks of their owners. vx is not affiliated with or endorsed by them.