Skip to content
Contents

Performance

Rindle is designed to provide both fast hydration (comparable to OLTP databases) and fast updates (like differential dataflow). It achieves this with a new IVM approach.

Chinook ×30 (105k tracks), in-process, same SQLite file and indexes. Rindle in sink mode over SQLite vs. SQLite re-running the query. MacBook M5 Max, measured 2026-09-16.

Time to first complete result from a query.

Rindle is already close to SQLite for most queries with limits, which are common in OLTP use cases. For queries without limits we are currently slower, and there are a few known open issues where we are much slower than SQLite.

We expect to reach parity with SQLite for most query forms.

Query Rindle SQLite Rindle vs. SQLite
top 50 tracks by length
(ORDER BY … LIMIT 50)
23.9 µs 22.4 µs 0.94×
one genre’s 100 longest tracks
(WHERE … ORDER BY … LIMIT 100)
48.7 µs 49.8 µs 1.0×
10 albums, each with its 10 newest tracks
(nested, LIMIT 10 both levels)
49.8 µs 33.3 µs 0.67×
100 newest albums with a track in a genre
(EXISTS … LIMIT 100)
1.3 ms 44.4 µs 0.03×*
all albums with all their tracks
(10,410 albums, 105,090 tracks, nested)
53.8 ms 21.9 ms 0.41×

* A known issue with EXISTS hydration that we’re working on.

CPU spent keeping a query live.

An app that polls SQLite re-runs its query on a timer, whether or not anything changed. Rindle does nothing until a write happens, and then does work proportional to the size of the edit, not the size of the result. Set how often you would poll and how long the task you’re waiting on takes:

QueryCPU/s
SQLite
CPU/s
Rindle
Rindle
advantage
Latency
SQLite
Latency
Rindle
top 50 tracks by length5.26 µs0.06 µs88×2.5 s3.6 µs
one genre’s 100 longest tracks10.7 µs0.063 µs170×2.5 s3.8 µs
10 albums, each with its 10 newest tracks7.42 µs0.062 µs120×2.5 s3.7 µs
100 newest albums with a track in a genre9.54 µs0.06 µs160×2.5 s3.6 µs
all albums with all their tracks4.32 ms0.087 µs50,000×2.52 s5.2 µs

Polling CPU is the re-run time divided by the poll interval. Rindle CPU is the update time divided by the task’s duration. Latency is the average time from a write to the new result: half the poll interval plus a re-run for polling, one update for Rindle. Polling faster cuts latency but multiplies its CPU.

Time to update many queries affected by a single write.

Rindle queries are deduplicated, but Rindle also shares work among closely related query families. As a result, the advantage increases with the number of outstanding live queries.

Live queries Rindle SQLite (re-run all N) Rindle vs. SQLite
1 3.6 µs 53.4 µs 15×
8 3.8 µs 435 µs 115×
64 6.3 µs 3.7 ms 588×
512 24.0 µs 29.7 ms 1,240×

Rindle against the Zero code it ports.

We expect the delta to grow as Rindle continues to be optimized.

Operation Rindle (Rust) Zero (TypeScript) Speedup
In-memory storage
scan 1,000 rows 3.6 µs 110 µs 31×
filtered fetch (~100 rows) 0.8 µs 12.8 µs 16×
start from middle (~500 rows) 2.4 µs 58 µs 24×
insert + delete a row 0.11 µs 3.1 µs 28×
edit a row 0.28 µs 3.9 µs 14×
SQLite storage
scan 1,000 rows 99 µs 673 µs 6.8×
filtered fetch (~100 rows) 17 µs 80 µs 4.7×
start from middle (~500 rows) 72 µs 369 µs 5.2×
insert + delete a row 2.9 µs 7.6 µs 2.6×
edit a row 2.7 µs 8.1 µs 3.0×