Sheetwrite

SHOWCASE / PERFORMANCE AND SCALE

One million rows, measured in front of you.

The grid below owns a paged datasource of exactly 1,000,000 deterministic rows. Live panels read the running engine through public APIs; committed numbers are benchmark artifacts with capture provenance. Protocol details live in the performance guide.

Booting the WASM engine…

Million-row paging

Cells resident now
0
Resident chunks
0
Resident cache
0 B
0% of budget
Dense equivalent
0 B
Page requests
0
Rows served / aborted
0 / 0

Full-dataset operations stay honest

Whole-dataset queries and exports refuse to fabricate unloaded rows. This expected bounded refusal returns a typed IncompleteDataError with exact loaded and total counts.

Wide pages

The second sheet is 121 columns wide and still paged — hydration is bounded by the visible window, never by the sheet.

Rows × columns
250,000 × 121
Served page
121 cols × 4,096 rows
Loaded cells (live)
0
Dense equivalent230.8 MiB
Paged, live0 B

Activate the wide sheet to watch pages hydrate; its live counters share the stats strip above.

Cache churn under a byte budget

Clean chunks live inside a 8.0 MiB cache — far less than 24 deterministic long jumps across the million-row feed will touch.

Worker rendering with honest fallback

The paint backend is chosen at construction, and rendererKind() reports what actually constructed — never what was requested. See the Worker rendering guide.

Paint backend (rebuilds the grid)

WASM boundary crossings, counted

Cell state lives in Rust/WASM; bulk commits cross the JS↔WASM boundary a constant number of times per operation — not once per cell. Each button commits a real, undoable transaction over 20,000 cells.

Committed benchmark evidence

The numbers below were not measured in your browser — they are committed benchmark artifacts, reproduced verbatim with capture provenance from the repository's benchmark protocol (bench/README.md).

Paged storage protocol

Source bench/results/paged-results.jsonpaged-full-v1 (protocol v1, full mode, 12 runs), 1,000,000 rows × 5 columns, 120-row pages, 32.0 MiB cache budget.

Committed paged-storage timings and allocation ceilings.
MeasurementMedianp95
Startup (1M-row workbook)0.06 ms0.78 ms
First page visible0.34 ms0.98 ms
Distant page (long jump)0.32 ms0.48 ms
Peak allocated530.0 KiB vs 62.0 MiB dense logical

Scenario probes

Committed allocation probes from the same artifact: chunks, loaded cells, and WASM memory delta per scripted scenario.
ScenarioChunksLoaded cellsAllocatedWASM Δ
empty000 B64.0 KiB
padding000 B64.0 KiB
viewport5150265.0 KiB320.0 KiB
scroll-11550,000795.0 KiB832.0 KiB
scroll-10125500,0006.5 MiB6.6 MiB
scroll-1006182,513,72832.0 MiB32.2 MiB
dirty1001005.2 MiB5.3 MiB

Cross-grid comparison capture

Source docs/src/generated/landing-bench.json — captured 2026-07-16 on Chromium 149.0.7827.55, 10 rounds, commit 47f164385f.

Median per-scenario speed ratio versus Handsontable across 14 interaction scenarios.
RowsScenarios comparedMedian ratioBest scenario
1,000147.2×scroll-right.top-left (96.7×)
10,0001410.7×scroll-right.top-left (111.3×)
100,0001426.3×scroll-right.top-left (201.2×)
1,000,00012 (2 incomplete on Handsontable)130.3×scroll-smooth.same-window (1522.2×)

Live panels measure this very page — page latency is a deliberate 90 ms simulation so lazy loading stays visible. Live numbers and committed benchmark numbers are not comparable to each other, and are never mixed.