• Stars
    star
    435
  • Rank 100,085 (Top 2 %)
  • Language
    TypeScript
  • Created almost 3 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Benchmarking Nx and Turborepo

Benchmarking Nx, Turbo, and Lage

Recording:

nx-turbo-recording

Repo contains:

  1. 5 shared buildable packages/libraries with 250 components each
  2. 5 Next.js applications built out of 20 app-specific libraries. Each app-specific lib has 250 components each. Each library uses the shared components.

Combined there are about 26k components. It's a lot of components, but they are very small. This corresponds to a medium size enterprise repo. A lot of our clients have repos that are 10x bigger than this, so this repo isn't something out or ordinary. And, the bigger the repo, the bigger the difference in performance between Nx and Turbo.

The repo has Nx, Turbo, and Lage enabled. They don't affect each other. You can remove one without affecting the other one.

Benchmark & Results (May 31)

npm run benchmark runs the benchmark. The following numbers produced by an M1Max MBP. On a Windows machine all the tools will get slower, and the delta between Nx and Turbo/Lage will get bigger.

  • average nx time is: 149.3
  • average turbo time is: 907.3
  • average lage time is: 1084.4
  • nx is 6.08x faster than turbo
  • nx is 7.26x faster than lage

Numbers from May 19:

  • average nx time is: 172.8
  • average turbo time is: 1134.1
  • average lage time is: 1109.9

Why is Nx faster than Turbo

Nx uses several optimizations to minimize the amount of computation required. For instance, it stores information about the repository on disk to be able to recompute only what is needed. It runs a daemon process that gets all the necessary data structures ready before the developer invokes a command. And the data structures are updated incrementally, usually in just a few milliseconds.

Is Nx always faster? No. The performance sensitive parts of Nx are written in Rust, but it is all wrapped into a Node.js process. Loading Node.js takes about 70ms (on a mac), regardless of what you do. You build 1000 projects, takes 70ms. You build 1 project, it takes 70ms. If you have a repo with say 10 files in it, running Turbo will likely be faster because it boots faster.

Yarn, npm, pnpm have a similar boot time to Nx, and folks don't mind. And, of course, it's worth asking whether a high-performance build tool is even required for a repo with 10 files in it.

Does this performance difference matter in practice?

The cache restoration Turborepo provides is likely to be fast enough for a lot of small and mid-size repos. What matters more is the ability to distribute any command across say 50 machines while preserving the dev ergonomics of running it on a single machine. Nx can do it. Bazel can do it (which Nx borrows some ideas from). Turbo can't. This is where the perf gains are for larger repos. See this benchmark to learn more.

Dev ergonomics & Staying out of your way

When some folks compare Nx and Turborepo, they say something like "Nx may do all of those things well, and may be faster, but Turbo is built to stay out of you way". Let's talk about staying out of your way:

Run nx build crew --skip-nx-cache and turbo run build --scope=crew --force:

terminal outputs

Nx doesn't change your terminal output. Spinners, animations, colors are the same whether you use Nx or not (we instrument Node.js to get this result). What is also important is that when you restore things from cache, Nx will replay the terminal output identical to the one you would have had you run the command.

Examine Turbo's output: no spinners, no animations, no colors. Pretty much anything you run with Turbo looks different ( and a lot worse, to be honest) from running the same command without Turbo.

A lot of Nx users don't even know they use Nx, or even what Nx is. Things they run look the same, they just got faster.

Lerna and Nx

Lerna 5.1 adds the ability to use Nx for task orchestration and computation caching (in addition to p-map and p-queue, which it had before). Given that Lerna uses Nx to run tasks, unsurprisingly, the numbers for Lerna and Nx will be very similar--it's the same powerful task orchestrator under the hood. This also means that Lerna supports distributed tasks execution (see above) and that it captures terminal output correctly.

Found an issue? Send a PR.

If you find any issue with the repo, with the benchmark or the setup, please send a PR. The intention isn't to cherry pick some example where Turbo doesn't do well because of some weird edge case. If it happens that the repo surfaces some edge case with how turbo works, send a PR, and let's fix it. We tried to select the setup that Turbo should handle well (e.g., Next.js apps). The repo doesn't use any incrementality which Nx is very good at. We did our best to make it fair.

More Repositories

1

state_management_ngrx4

TypeScript
208
star
2

DCI-Sample

A sample application illustrating the Data Context Interaction paradigm (in Ruby)
Ruby
152
star
3

router_mailapp

TypeScript
114
star
4

angulardart-sample-app

A sample Web application built using AngularDart
Dart
102
star
5

RuntimeTypeChecks

Runtime type checks for JavaScript and TypeScript
TypeScript
85
star
6

ng1ng2router

TypeScript
73
star
7

essential-angular-book-app

TypeScript
66
star
8

router_lazyloading

TypeScript
62
star
9

state-app-examples

TypeScript
57
star
10

router-store

TypeScript
51
star
11

interstellar

Nx: On how to make your CI 10 times faster with 1-line config change
TypeScript
50
star
12

fpdart

Functional Programming in Dart
Dart
47
star
13

guinness

A port of the Jasmine testing framework to Dart.
Dart
43
star
14

upgrade-book-examples

TypeScript
38
star
15

SimpleMVP

VINT is a library for building single-page applications in Dart.
Dart
36
star
16

hammock

AngularDart service for working with Rest APIs
Dart
34
star
17

tex

tex
TypeScript
18
star
18

chat-dart

Dart
17
star
19

frp_dart

Functional Reactive Programming in Dart
Dart
15
star
20

custom-renderer

Experiments with Angular Renderers
TypeScript
15
star
21

HabiticaClient

App built using Angular 2 and Immutable JS
TypeScript
15
star
22

ngselectors

Redux-style selectors for Angular 2.
TypeScript
15
star
23

angular2-immutable-kanban

JavaScript
14
star
24

marble_testing_and_race_conditions

TypeScript
14
star
25

CoolCodeSnippets

Collection of interesting code snippets in JavaScript and TypeScript
TypeScript
13
star
26

actors

Actors.Dart - Building Distributed Applications on the Web Platform
Dart
12
star
27

databinder

DataBinder is a Dart library implementing data binding via object mirrors.
Dart
12
star
28

composing-ngrxstore-reducers

TypeScript
11
star
29

large-repo

TypeScript
11
star
30

router-store-prototype

TypeScript
11
star
31

polymer_dart_sample_app

Auctions (a sample application built using Polymer.Dart)
Dart
10
star
32

lerna-dte

"Lerna & Distributed Task Execution" Example
TypeScript
9
star
33

dartmocks

DartMocks is a mock framework for Dart inspired by RSpec.
Dart
9
star
34

rubyast

Allows AST Transformations for Ruby.
Ruby
8
star
35

webpack_angular_dev_and_prod

TypeScript
6
star
36

chat-node

JavaScript
6
star
37

XmlTransformer

Groovy
6
star
38

ng-conf-app

TypeScript
6
star
39

nx-dev-ergonomics

Nx and its wonderful DX
TypeScript
5
star
40

router-spinners

TypeScript
5
star
41

Gradle-Project-Generator

Groovy script generating Gradle projects
Groovy
5
star
42

Testing-Framework--Picard-

Ruby
4
star
43

libandapp

TypeScript
4
star
44

novosibirsk

TypeScript
4
star
45

TypedFields

Ruby Gem adding AR like type conversions for regular ruby objects
Ruby
3
star
46

atscript_todomvc

CSS
3
star
47

serializers

Serializers is a Dart library for serializing objects into maps.
Dart
3
star
48

AST-Transformations

Groovy
3
star
49

csw-catalog

CSW 2.0.2 + Client
Ruby
3
star
50

router-nested-outlets

TypeScript
3
star
51

use-case-service

TypeScript
3
star
52

GroovyMigrationScript

Performs database migrations
Groovy
2
star
53

learnwords

a simple application for learning new words
Ruby
2
star
54

dci-in-ruby.github.com

DCI in Ruby
Ruby
2
star
55

routerrefresh

TypeScript
2
star
56

PersistentHashMap

An implementation of a map that can be saved to a file and can be read from a file.
Groovy
2
star
57

vimconfig

my vim config
Vim Script
2
star
58

InspectPartials

A small gem showing partial names
Ruby
1
star
59

TinyDiary

Small Grails app helping you to keep track of your productive and unproductive days
Groovy
1
star
60

rmilk

A console application for managing your remember-the-milk tasks
Ruby
1
star
61

vint

Dart
1
star
62

dotfiles

Shell
1
star
63

patched_cli

JavaScript
1
star
64

RTM

Ruby
1
star
65

jruby_ast_transformations

Ruby
1
star
66

robots

Clojure
1
star
67

emacs.d

Emacs Lisp
1
star
68

pallets-samples

Ruby
1
star
69

nx-large-repo-perf

JavaScript
1
star
70

JasmineDart

Dart
1
star
71

demoapp

TypeScript
1
star
72

RailsH2

Ruby
1
star
73

TestProject

Showing how to publish artifacts using Gradle
1
star
74

fake-server

TypeScript
1
star
75

angulardart-angularjs

Side-by-side comparison of AngularDart and AngularJS.
Dart
1
star
76

vladivostok_demo

TypeScript
1
star
77

rabbitmq_samples

Ruby
1
star
78

oald_parser

a simple parser of the oxford online dictionary
Ruby
1
star
79

hammock_mapper

Hammock Mapper
Dart
1
star
80

samplenx

TypeScript
1
star
81

westormsettings

1
star
82

LogsUI

Groovy
1
star
83

lazyload_angular13

TypeScript
1
star