Benchmark Snapshots
These numbers are local prototype measurements, not product performance guarantees. They are useful for comparing architectural directions under the same synthetic CVL fixture.
2026-05-06 Tiny Fixture, Four Contenders
Command:
npx --yes pnpm@10.33.2 --filter @cv/cvl-engine-bench bench --adapter all --preset tiny --rounds 3 --measure-update-bytes --json
Fixture:
- operations:
1,892 - nodes:
637 - selection groups:
411 - rendered nodes:
93 - rendered lines:
94
| Adapter | Total responsiveness | Wall time | State bytes | Update bytes | Update measurement | Selection index | Render projection |
|---|---|---|---|---|---|---|---|
| In-memory baseline | 40.290 ms |
43.077 ms |
316,971 |
1,100,751 op-log estimate |
0 ms |
6.981 ms |
1.410 ms |
| Yjs normalized | 144.290 ms |
351.666 ms |
591,549 |
1,823,670 CRDT update |
189.704 ms |
44.062 ms |
3.827 ms |
| Loro Tree-first normalized | 819.310 ms |
1,006.025 ms |
381,512 |
2,218,480 CRDT update |
159.709 ms |
447.005 ms |
3.804 ms |
| Loro Extended-style | 719.393 ms |
948.483 ms |
255,247 |
2,276,976 CRDT update |
203.045 ms |
235.674 ms |
3.269 ms |
2026-05-06 Standard Fixture, Responsiveness Mode
Command:
npx --yes pnpm@10.33.2 --filter @cv/cvl-engine-bench bench --adapter <adapter> --preset standard --rounds 1 --json
Fixture:
- operations:
30,958 - nodes:
7,857 - selection groups:
3,287 - rendered nodes:
1,016 - rendered lines:
1,020
| Adapter | Total responsiveness | Wall time | State bytes | Selection index | Render projection | Status |
|---|---|---|---|---|---|---|
| In-memory baseline | 130.706 ms |
136.055 ms |
3,284,495 |
64.132 ms |
11.084 ms |
completed |
| Yjs normalized | 794.037 ms |
815.152 ms |
7,759,607 |
406.728 ms |
42.158 ms |
completed |
| Loro Extended-style | 4,886.953 ms |
5,003.537 ms |
3,312,954 |
1,951.812 ms |
20.971 ms |
completed |
| Loro Tree-first normalized | n/a | n/a | n/a | n/a | n/a | timed out at 90s; reached 30,000 / 30,958 ops at about 61s in a progress probe |
Interpretation
- The local normalized engine is the algorithmic ceiling. It shows what the UI/worker selector layer should feel like when it is not paying CRDT bookkeeping costs.
- The runner now separates
total responsivenessfrom wall time and update-byte export time. This matters because byte export can dominate small-fixture CRDT runs. - Yjs normalized is the fastest completing CRDT contender on the standard fixture after benchmark-only invariant sweeps are disabled. Its tradeoff is the largest serialized state in this fixture.
- Loro Extended-style keeps the smallest serialized state and completes the standard fixture, but selection-index reads and select-group writes are still too expensive.
- Loro Tree-first normalized is no longer competitive at the standard fixture scale without deeper read/index optimization.
- Single runs can be noisy, especially when checks run in parallel. Use repeated rounds and isolated runs before making a substrate decision.