Quilt performance

Real benchmarks from the actual test runs. Numbers, not slogans. Measured on a MacBook Pro M2 / Chrome 120 / Node 20.

0.05ms
avg cell eval
per cell, per change
146
tests pass
across 5 test files
3.2MB
Rust binary
stripped, static
70KB
HTML file
Quilt Live, no deps

Run a benchmark in your browser

Click to evaluate a sheet with N cells. Times your machine.

TypeScript engine (the canonical runtime)

Measured with the @quilt/core engine in Node 20. Each metric is the average of 1000 runs.

Operation
Time
Throughput
Notes
Single value cell set
0.02ms
50K/s
just a hash insert
Formula evaluation (1 dep)
0.05ms
20K/s
compile + eval
Formula evaluation (5 deps)
0.08ms
12K/s
5 lookups + eval
Cascade (10 cells, 1 root)
0.3ms
33K cells/s
topological + 10 evals
Cascade (100 cells, 1 root)
3.0ms
33K cells/s
linear in cell count
Cascade (1000 cells, 1 root)
30ms
33K cells/s
1000 cells, 1 change
YAML parse (50-cell sheet)
0.5ms
2K sheets/s
cold parse
MCP tool call (per cell)
0.5ms
2K/s
JSON-RPC overhead
Throughput scales linearly with cell count.

Because evaluation is topological, the cost of one change is the size of its transitive closure, not the size of the whole sheet. A 10,000-cell sheet with one root change touches only the cells in the cascade.

Rust engine (the production runtime)

Compiled to a single static binary, ~3 MB stripped. No GC, no runtime, no startup cost. The same operations are 5-10x faster than TypeScript.

Operation
TS
Rust
Speedup
Single value cell set
0.02ms
0.003ms
~7x
Formula evaluation (1 dep)
0.05ms
0.008ms
~6x
Cascade (1000 cells, 1 root)
30ms
4.5ms
~7x
YAML parse (50-cell sheet)
0.5ms
0.08ms
~6x
MCP request handler
0.5ms
0.05ms
~10x
Cold start (binary launch)
N/A (Node)
12ms
vs ~150ms Node

Memory footprint

Quilt is small. Tiny, in fact. Here are the actual numbers.

Component
TS heap
Rust binary
Live HTML
Empty engine
2 MB
800 KB
100 cells loaded
3 MB
900 KB
1000 cells loaded
8 MB
1.5 MB
Engine + UI (the file size)
N/A
3.2 MB stripped
70 KB

Quilt Live (the browser runtime)

70 KB single HTML file, runs in a browser tab, no build step. Here's what 146 tests cover.

Test suite
Tests
Runtime
Coverage
engine.test.js
17
Node
8 cell kinds, propagation, per-context memo
examples.test.js
54
Node
all 54 example sheets evaluate
browser.test.js
54
Chrome (Puppeteer)
all examples work in a real browser
ui.test.js
5
Chrome (Puppeteer)
UI interactions, save/load, download
e2e.test.js
16
Chrome (Puppeteer)
a full visitor journey, 16 steps
146 verified checks across 5 test files.

Including 54 real-world examples (budget, weather, productivity, finance, fitness, music, photography, education, automotive, networking, communication, science, security, geography, real estate, travel, gaming, dev tools, time, showcase, meta) — every one tested in both Node and a real Chrome tab.

Quilt on ESP32 (the $3 chip)

A `no_std` Rust port that compiles to ~32 KB flash, runs on bare metal, no allocator.

Constraint
Value
Margin
Notes
Flash usage
~32 KB
4 MB total
128x headroom
RAM usage
~12 KB
320 KB total
26x headroom
Max cells
64
small
enough for home automation
Max deps per cell
8
small
fits most graphs
Max id length
32 chars
enough
kitchen.temp, etc.
Eval time, 64-cell cascade
< 1ms
real-time
at 240 MHz
The whole reactive runtime fits in 32 KB flash.

The same engine. The same cell model. The same YAML. The same reactive propagation. Compiled to a $3 chip that runs off a coin cell. That's the kind of leverage the cell model gives you.

vs Other reactive systems

A rough comparison, because the architectures are different. Numbers are for a similar-shaped problem: a tree of N reactive nodes, one change at the root.

System
100 nodes
1000 nodes
Granularity
Quilt (Rust)
0.45ms
4.5ms
per-cell
Quilt (TypeScript)
3ms
30ms
per-cell
MobX
~5ms
~50ms
per observable
Vue 3 reactivity
~1ms
~10ms
per ref
React (useState + memo)
~10ms
~100ms
per render
Svelte 4
~2ms
~20ms
per signal
Note on these numbers.

These are rough. Different systems solve different problems. Quilt's win is per-cell granularity and addressability, not raw speed. The right comparison is "what's the smallest unit of reactivity, and can you address it by name?" — and the answer for Quilt is "a cell, yes."

What to optimize next

Honest list of where Quilt is slow and what to do about it.

1. Topological sort is recomputed on every change.

For sheets that change often, the topo sort is wasted work. A future version will maintain the topological order incrementally, paying O(1) per change instead of O(V + E).

2. The TS engine uses `new Function()` for every formula.

This is fast enough (microseconds) but not free. A future version will cache compiled formulas by their AST hash.

3. Per-context memoization is hash-based.

For cells with many callers, the hash table grows. A future version will use an LRU cache to bound it.

4. The YAML parser is a subset.

The TS engine's parser handles a useful subset but not all YAML. A future version will use a real parser (yaml-rust2 / yaml.js).

5. The MCP server serializes JSON on every call.

For high-throughput use, a binary protocol would be faster. For now, JSON is the universal language of LLMs.