ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
Topics
sre111localhost lab102performance70python58javascript47bundle size36benchmarking35node.js35web development21typescript19benchmark16content creation15All topics
About
Loading article…

ShopperCove

Hands-on notes on developer tools, written after the tool has actually been run.

All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove

On this page

  1. What I tested
  2. Is Turbo faster than Nx on cold builds?
  3. What do you lose leaving Nx?
  4. Should you leave Nx for Turbo?
  5. Sources
  6. Related
  1. Blog

Should You Leave Nx? 3378ms vs 1177ms

Turbo 2.11.7 vs Nx 23.2.1 on 7 packages / 336 JS files: cold median 1177 ms vs 3378 ms (~2.9x). Warm both 7/7 local cache hits (Turbo wall ~138 ms / tool ~16 ms; Nx wall ~668 ms with daemon / tool ~31 ms).

5 October 2026·5 min read

Summary
On this page
  1. What I tested
  2. Is Turbo faster than Nx on cold builds?
  3. What do you lose leaving Nx?
  4. Should you leave Nx for Turbo?
  5. Sources
  6. Related

On a 7-package npm workspaces monorepo (336 JavaScript source files), Turbo 2.11.7 took a cold median 1177 ms and Nx 23.2.1 took 3378 ms (~2.9x). Warm local cache was 7/7 hits for both: Turbo wall median 138 ms (tool Time ~16 ms FULL TURBO), Nx wall median 668 ms with the daemon on (tool Run duration ~31 ms).

Short answer: leave Nx for Turbo when you want a thin task runner and faster cold CI on a simple package-script graph. Keep Nx when you need generators, project graph plugins, and a full monorepo framework. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM Linux cloud box, Node 20.19.2, tested 5 Oct 2026 (about 23:35 to 23:45 IST). Shared box; tools interleaved each round.
  • Fixture: npm workspaces with 6 libraries (@bench/pkg-a … pkg-f) and 1 app (@bench/web), 336 .js files under src/. Each build script reads its src/, does a small CPU hash loop, and writes dist/index.js.
  • Tools: turbo 2.11.7 (turbo run build) and nx 23.2.1 (nx run-many -t build --all). Turbo packageManager field set; Nx targetDefaults.build.cache with outputs {projectRoot}/dist/**.
  • Timing: five interleaved cold runs (Turbo --force; Nx --skip-nx-cache), then five interleaved warm cache-hit runs. Warm Nx measured with NX_DAEMON=true after a daemon warmup. Wall-clock via perf_counter around the full CLI.
  • Findings: cold medians Turbo 1177.19 ms (1133 / 1177 / 1196 / 1177 / 1299) vs Nx 3377.905 ms (3209 / 3135 / 3378 / 3440 / 3443). Warm: both 7/7 cache hits; Turbo wall 135–152 ms (tool Time 13–26 ms); Nx wall 625–715 ms (tool Run duration 30–36 ms).
  • One surprise: on cache hits the tools themselves report similar task times (~16–31 ms), but Nx wall clock stayed higher because each CLI call still pays Node startup even with the daemon on.
  • Not tested: remote cache (Vercel Remote Cache / Nx Cloud), affected-only runs, Nx generators or @nx/* executors beyond nx:run-script, pnpm/yarn workspaces, Windows/macOS, a 100+ package graph.

Is Turbo faster than Nx on cold builds?

ToolCold median (wall)Cold runs (ms)Warm cacheWarm wall medianTool-reported warm
Turbo 2.11.71177 ms1133 / 1177 / 1196 / 1177 / 12997/7138 ms~16 ms FULL TURBO
Nx 23.2.13378 ms3209 / 3135 / 3378 / 3440 / 34437/7668 ms~31 ms Run duration

On this fixture Turbo finished cold builds about 2.9x faster. Both restored from local cache on every warm run. If your CI is mostly cold or cache-miss work on npm-script tasks, Turbo's lower overhead showed up clearly here.

Monorepo task runners sit next to bundler and package-manager choices. The Rspack vs Webpack post and the Rolldown vs Rollup post cover compile/bundle speed; the pnpm vs npm vs Bun post covers install speed. This post is only the task-orchestrator decision. For a Turbo point-release note on this site, see Turborepo 2.11.7.

What do you lose leaving Nx?

Nx is a monorepo platform, not only a cache wrapper. You lose first-party generators, inferred project graph plugins, module-boundary rules, and Nx Cloud workflows if you drop it for Turbo alone. Teams already deep in @nx/react or @nx/next executors should not treat this 7-package npm-script bench as a migration green light.

Also expect different config shapes. Turbo stayed close to package.json scripts plus turbo.json tasks. Nx needed explicit outputs under targetDefaults before local cache hit 7/7 on this fixture.

Should you leave Nx for Turbo?

SituationMy pick
Thin npm/pnpm workspaces, scripts already define build/lint/testPrefer Turbo; re-measure your graph
You need generators, boundaries, or Nx pluginsStay on Nx
CI is mostly cold or cache-bust builds on small packagesTurbo's cold ~2.9x here is the signal to test
You already pay for Nx Cloud remote cache and it is warmStay; this lab did not test remote cache
First PR would rewrite every project.json / executorStay on Nx unless the team wants a thin runner

Bottom line: on 7 packages and 336 JS files, Turbo cold median was 1177 ms and Nx was 3378 ms, with both hitting full local cache when warm. Who should not switch yet: teams that depend on Nx generators and plugins. Everyone else comparing task runners should run the same cold/warm pair on their own workspace.

How this was made: I built the workspaces fixture, ran interleaved Turbo and Nx builds on the ShopperCove test box, and kept the timing JSON; the write-up was drafted with AI help and checked against that output.

Sources

  • 01turbo.build/repo/docs
  • 02github.com/vercel/turborepo
  • 03nx.dev/docs
  • 04github.com/nrwl/nx
  • 05npmjs.com/package/turbo
  • 06npmjs.com/package/nx

Related

  • 01shoppercove.com/blog/swc-vs-esbuild-babel
  • 02shoppercove.com/blog/vite-8-3-2-renderbuilturl-bundled-dev-sourcemaps-october-2026
  • 03shoppercove.com/blog/jest-vs-vitest
  • 04shoppercove.com/blog/typescript-7-should-you-upgrade
monorepoturboreponxbenchmarkingcitask runnerbuild performancenpm workspaces

Lab evidence

What I found running this

Hands-on on ShopperCove box 5 Oct 2026 ~23:35-23:45 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 20.19.2). Fixture: npm workspaces, 7 projects (6 libs + 1 app), 336 JS src files; build scripts CPU-hash src → dist. Versions: turbo 2.11.7, nx 23.2.1. Cold: 5 interleaved (turbo --force; nx --skip-nx-cache). Cold medians: turbo 1177.19 ms (1133.12/1176.741/1195.795/1177.19/1299.236); nx 3377.905 ms (3209.046/3135.461/3377.905/3440.206/3442.991). Warm: 7/7 cache hits both; turbo wall median 137.716 ms (daemon N/A; tool Time ~16 ms); nx wall median 668.264 ms with NX_DAEMON=true (tool Run duration ~31 ms). Raw: /workspace/bench-turbo-nx/res-turbo-nx.json. Not tested: remote cache, Nx generators/plugins beyond nx:run-script, pnpm/yarn, Windows/macOS, 100+ package graphs. No affiliate.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Keep reading

  • Playwright vs Cypress: 1.47s vs 4.24s Smoke

    Playwright 1.55.1 Chromium vs Cypress 14.5.4 Electron on one local smoke (visit /, assert h1, click, assert). Warm medians (7 rounds after 1 warm-up): Playwright 1,466 ms vs Cypress 4,243 ms (~2.9x). Disk: PW node_modules ~12 MB + cache ~918 MB; Cypress node_modules ~23 MB + cache ~601 MB. Fixture /workspace/bench-pw-cy/.

    Hands-on6 Oct 20264 min read

  • Turbo vs Lage: 1.97s vs 3.01s Cold Build

    Turbo 2.11.7 vs Lage 2.17.0 on a 4-package diamond npm workspace (250k-iter build scripts): cold wall medians 1,974 ms vs 3,007 ms (~1.5x); Turbo warm 4/4 cache hits ~0.50 s; Lage warm ~1.49 s. Lage required git init.

    Hands-on5 Oct 20264 min read

  • esbuild-register vs jiti: 343ms vs 540ms Cold

    esbuild-register 3.6.0 vs jiti 2.7.0 on a 61-file TypeScript graph: cold wall medians 343 ms vs 540 ms (~1.57x); after jiti disk cache warm, 185 ms vs esbuild-register 350 ms. Same printed result 970.

    Hands-on5 Oct 20264 min read