Zero 1.8
Observability and Reliability
Installation
npm install @rocicorp/zero@1.8You can now use zero-cache from GHCR:
docker pull rocicorp/zero:1.8.0
# or
docker pull ghcr.io/rocicorp/zero:1.8.0Overview
Zero 1.8 improves observability, performance, and reliability.
Features
- Request-header forwarding:
zero-cachecan forward selected WebSocket upgrade headers to custom APIs usingZERO_MUTATE_ALLOWED_REQUEST_HEADERSandZERO_QUERY_ALLOWED_REQUEST_HEADERS. (#6144, thanks @tjenkinson!) - GHCR Docker images: Zero images are now published to
ghcr.io/rocicorp/zeroas well as Docker Hub. (#6161) - Mutator result type:
MutatorResultis now exported from@rocicorp/zerofor typing helpers that await.clientor.server. (#6223) - Operational metrics:
zero-cacheadds metrics for API calls and startup, initial sync and replication slots, and Litestream backup and restore. (#6203, #6208, #6191, #6199, #6210) - Stability metrics: New serving-lag, CVR, and WebSocket metrics and replication flow-control metrics help diagnose delayed updates, reconnects, and backpressure. (#6157, #6214, #6207)
Performance
Zero 1.8 speeds up replication of large transactions, maintenance of queries that use limit(), and client-side query hydration.
Replicating Large Transactions
Bulk imports, backfills, or migrations often change thousands of rows in a single Postgres transaction. These large transactions replicate about 1.5x faster in Zero 1.8.
Replicating Large Transactions
Measured on M5 Pro. Higher is better.
Maintaining limit() Queries
Consider a query like this:
zql.issue
.where('status', 'open')
.orderBy('created', 'asc')
.limit(50)Zero can fulfill this query using an index on either status or created. If it decides to use the created index, Zero might have to consider many rows before it finds 50 matches. That is unavoidable.
But when changes to the data move rows in or out of the first 50 results, Zero 1.7 repeated the work to find the first 50 results, making incremental updates slower than necessary. Zero 1.8 fixes this.
In benchmarks, when the last returned row was 50,000 rows into the index, incremental updates were 2x faster in Zero 1.8. When it was 100,000 rows in, updates were over 50x faster in Zero 1.8.
Maintaining limit() Queries
Measured on M5 Pro. Higher is better.
Client-Side Hydration
Zero runs queries first on the client, then on the server. The initial client-side hydration got faster in Zero 1.8. For example, this query returns initial data from client about 1.3x faster in Zero 1.8:
zql.issue.related('creator').related('comments')Client-Side Hydration
Measured on M5 Pro. Lower is better.
Fixes
- Logical replication now reconnects when the inbound Postgres stream goes silent.
- Postgres writes no longer use sockets after disconnection.
- The Drizzle adapter now handles array-mode results from Drizzle 1.0 RC
prepareQuery. (thanks @typedrat!) - z2s now compiles queries using
start, and SQLite fetches handlenullstart-cursor fields. - Queries no longer appear
completewith stale or empty results after reconnect. - React Native reads now work with
op-sqlitev17. - View-syncers no longer fail while the first backup is uploading or retry before a restorable backup exists on cold start.
- Zero Docker images now choose the correct default sync-worker count.
- Change-stream catch-up now respects flow control, preventing unbounded in-memory backlogs.
Breaking Changes
None.