Benchmarks

Local query and edit measurements. These results do not compare Tablin with another grid or guarantee application responsiveness.

Cold queries

A fresh 100,000-row comparison on 31 October 2026, with indexing enabled in both versions. Median milliseconds from five measured iterations after two warmups. Cold-query time includes retained index preparation.

Operation Before After
Main cold query 136.556 111.898
Worker cold query 223.144 187.943
Main ingest + cold 252.815 223.673
Worker ingest + cold 332.572 294.599

Cold medians fell 18.1% on the main path and 15.8% on the worker path. Paired ingest-plus-query medians fell 11.5% and 11.4%; the work was not shifted into slower ingestion. Changes reduce repeated built-in decoding, operand dispatch, key allocation, and projection admission scans. The custom stable sort, incremental index, cancellation, and memory reservations remain enabled.

Apple M2 Max, 32 GiB RAM, macOS Darwin 25.3.0 arm64, Node v25.2.1. The same seeded query accepts 21,654 records. Every complete result and mixed-edit transition was verified. Builds and local checks were paused during measurement. Compare before and after within this run; the earlier reports below have different absolute timings. These engine timers exclude rendering and input.

Edits

Recorded earlier on 31 October 2026, before the cold-query pass. These controls used the same 100,000-record fixture with incremental indexing disabled and enabled. Times below are median milliseconds from five measured iterations after two warmups.

Operation Off On
Main amount edit + read 75.551 0.197
Main status edit + read 74.906 0.146
Worker amount edit + read 119.680 0.178
Worker status edit + read 103.575 0.202
Main cold query 75.795 96.577
Worker cold query 146.367 164.250

Small relevant edits update a custom persistent index. A cold query still filters and sorts the complete source, then builds the index on the host. This increased cold-query time by 27.4% on the main path and 12.2% on the worker path. Larger or unsupported edits rebuild. Indexing can be disabled for static workloads.

Each edit total sums its patch and following 200-row read before taking the median. Every complete result was checked against an independent filter/sort, including ten mixed transitions through membership boundaries and sort ties. Indexed runs performed twelve relevant updates with one full query and no fallbacks. Environment: Apple M2 Max, 32 GiB RAM, macOS Darwin 25.3.0 arm64, Node v25.2.1. These are engine timings; they exclude rendering and input.

Browser

The final cold-query build with indexing enabled used headless Chromium 156 at 1440 × 960 CSS pixels, two warmups, and five measured iterations. Median cold-query settle time was 105.0 ms on the main path and 160.0 ms with a worker. The median largest frame callback gap was 105.1 ms and 33.6 ms respectively. There was no fresh paired before/after browser run; these figures do not establish a browser latency reduction or smooth frames.

In the compiled Orders playground, status filtering measured 107.347 ms, sorting 250.760 ms, and search 425.139 ms. Those medians include browser automation, rendering/polling, and the 120 ms search debounce. All 4,971 matching CSV records were verified. Heap peaks, real devices, sustained edits, and other browsers remain unmeasured.

Baseline

Recorded on 31 October 2026 from the synchronous local-provider foundation, before the worker milestone. The fixture contains 100,000 seeded plain records. Its query filters open orders by amount, then sorts by amount and row key.

Environment: Apple M2 Max, 12 logical CPUs, 32 GiB memory, macOS Darwin 25.3.0, arm64, Node v25.2.1.

Results

Times are milliseconds. Seven measured iterations followed two warmups.

Operation Median p95
Ingest 100,000 records 121.097 184.570
First sort/filter 36.556 62.807
Cached 200-row window 0.048 0.051
Single cell patch 0.085 0.271
First read after patch 30.576 33.561

With seven samples, nearest-rank p95 equals the maximum. Sub-millisecond results are sensitive to scheduling and measurement overhead.

Method

The fixed-seed fixture has five fields: order ID, customer, region, amount, and status. The query accepts exactly 21,654 records. A single customer-name patch does not change filtering or order.

Outside the timers, the benchmark checks every accepted row’s key, values, and order against an independent filter/sort calculation. It also checks exact counts, window boundaries, mutation visibility, previous-page stability, and unchanged host records.

Inside the private workspace, rebuild before running:

pnpm build
node scripts/benchmark.mjs --iterations=25

The benchmark writes environment details, samples, median, p95, minimum, maximum, and verification results as JSON. It requires at least five measured iterations.

Limits

This baseline invalidates derived query results after every committed change. Its read after an unrelated customer edit therefore scans and sorts the records again. The patch timing covers only the indexed storage update and validation.

The timers exclude rendering, layout, scrolling, browser input, networking, and fixture generation. They do not measure peak or retained memory, garbage collection pauses separately, cold process startup, sustained edits, multiple providers, or concurrent interaction.

One query on one machine is a regression baseline. Use browser interaction and broader workloads to judge an application. Worker execution and incremental query work are tracked on the status page.