Zero 1.7
Query Correctness and Performance
Installation
npm install @rocicorp/zero@1.7Overview
Zero 1.7 includes improvements to query correctness, performance, and operational safety.
Features
- Immutable query result updates: Query result updates now preserve references for unchanged subtrees, improving compatibility with React memoization and Solid reactivity without the earlier eager-expansion regression. (#6093)
- Additional Postgres scalar types: Zero now syncs selected text-represented Postgres scalar types, including network/address types,
pg_lsn, and theisnextension family, asstringcolumns. These columns can also participate in Zero primary keys. (#6099) - Replication lag diagnostics: Added a
replication.last_total_laggauge so operators can distinguish actual replication lag from a stalled lag-report stream. (#6042)
Performance
Zero 1.7 improves the performance of replication and exists queries.
Replication
Replication in Zero 1.7 is about 1.8x faster than Zero 1.6 in benchmarks. Initial sync is also modestly faster.
In real-world workloads we saw better results. One customer workload on Cloud Zero saw max sustainable replication increase from ~750 writes/second to ~2500 (> 3x faster).
Replication
Normalized replication throughput. Higher is better.
Flipped Exists Queries
In a query like doc.where("id", id).whereExists('comment').limit(10), the order that tables are considered matters for performance. If there are only a few child rows per parent, it's much faster to find children first, then find the corresponding parents, then sort and limit. Zero does this automatically using a process called join flipping.
Flipped joins are very common since exists is used in permissions, and in many systems each user has access to only a small subset of total rows.
These kinds of queries got faster in Zero 1.7. In simple cases where each child has a unique parent (e.g., doc -> comment), Zero 1.7 is roughly 3x faster. In cases where each child has multiple parents (e.g., user -> doc_acl), Zero 1.7 is dramatically faster – reaching ~100x faster at 10k results.
Flipped Exist - Unique Parent
Normalized throughput for flipped exists with unique parents. Higher is better.
Flipped Exist - Non-Unique Parent
Normalized throughput for flipped exists with non-unique parents. Higher is better.
Fixes
- WebSocket close code
1009could trap a client in a reconnect loop by repeatedly resending the same oversized message. - Inspector/analyze-query could show a query plan different from the actual plan generated by the table source.
- Duplicate bundled copies of runtime peer dependencies could break customer-observable behavior such as
Pool instanceofchecks and React single-instance assumptions. - Singular and plural queries with the same AST could incorrectly share a client view.
- React and Solid queries with nested relationships using
one()vslimit(1)could share a view cache entry and return the wrong nested shape. - Removing a query could trigger an assertion.
LIKE/ILIKEmatching in the JS query engine used multiline regex behavior instead of dotall behavior, causing mismatches for strings containing newlines. (thanks @sravan27!)- Range filters (
<,<=,>,>=) could use ordering that differed from SQLite/Postgres ordering. (thanks @sravan27!) - SQLite replica
LIKE/ILIKEbehavior could diverge from Postgres and the in-memory JS matcher. - SQLite replica
ILIKEdid not match non-ASCII case variants such asMÜLLERandmüller. - Litestream-backed deployments could purge change-log entries based on stale claimed backup progress rather than actual backup state. #6123
- Query hydration and pipeline failures now include the query hash, transformation hash, and custom query name when available.
- "vended rows" inspector feature was slow for large numbers of rows
- Logging code created gc pressure throughout system
Breaking Changes
None.