Skip to content
vxvx
GitHubBlueskydev.toRSS
Blog

Why vx is fast: five decisions, not a trick

What vx adds to a run with nothing changed, with no daemon, and the five design choices behind that number.

With nothing changed, vx adds 559 ms to a 9,603-task run. No daemon keeps it warm.

Nothing changed
vx559 ms
Turborepo689 ms
Nx12.07 s
Vite Task10.71 s
Nothing changed, outputs restored
vx1.04 s
Turborepo1.32 s
Nx11.94 s
Vite Task10.57 s
Cold build
vx6.68 s
Turborepo11.18 s
Nx3 min 12 s
Vite Task8.51 s
Cold build: CPU the runner burns
vx42.19 s
Turborepo1 min 19 s
Nx5 min 31 s
Vite Task24.17 s
The table
Time added over the ideal run, 1,601 projects, 9,603 tasks vx Turborepo Nx Vite Task
Nothing changed 559 ms 689 ms 12.07 s 10.71 s
Nothing changed, outputs restored 1.04 s 1.32 s 11.94 s 10.57 s
Cold build 6.68 s 11.18 s 3 min 12 s 8.51 s
Cold build: CPU the runner burns 42.19 s 1 min 19 s 5 min 31 s 24.17 s

Synthetic monorepo, 1,601 projects, 30 levels · concurrency 10, native configs · benchmarks

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.

Five design choices make that number. Each one also makes the cache harder to get wrong.

This repo, 48 MB · linux x64, 4 cores, warm page cache · 2026-10-23

Git keeps a hash of every tracked file. vx asks git instead of reading them. Clean-tree key derivation costs zero source-file reads.

A dirty file gets the same hash git would give it, so a commit never changes a key (how).

vx starts the task with the most work below it first. Counting that with a graph walk took 8.5 s of a 10 s run on a 1,090-package graph.

Bitsets do it in milliseconds (how).

3. A hit on an up-to-date tree is a few stat calls

Section titled “3. A hit on an up-to-date tree is a few stat calls”

vx wipes outputs before a task runs, so it knows what a hit leaves on disk. If each file still matches (size, mode, millisecond mtime, inode and ctime), there is nothing to restore.

The local cache stores plain files and the kernel copies them.

Metadata and the captured stdout live in the index (the stdout in a side table), so the log comes back with one SQL read (how).

A run reads .vx/projects.lock.json and evaluates no config. No telemetry plugin means no listener and no git spawn. A plugin that skips a task costs nothing.

Every change to this path ships with a measured before and after (Optimizations). 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.