Zero 1.10

Unique Keys and More Reliable Replication

Installation

npm install @rocicorp/zero@1.10

Overview

Zero 1.10 catches invalid scalar queries during type checking and makes replication, backups, and recovery more reliable.

Features

  • TypeScript now checks that {scalar: true} subqueries match a full primary or unique key. Schemas can declare unique Postgres indexes with .unique(...). (#6307)
  • Replication now adapts to slow view-syncers. It restarts serving replicas that stay behind and prevents a backup replica that is still catching up from slowing down healthy replicas. (#6357, #6358, #6451)
  • After initial sync or a backup destination change, Zero waits for a usable backup before reporting ready or taking over replication. (#6313, #6401)
  • Opt-in Litestream v5 backups give each replica its own backup path, and Zero acknowledges upstream changes only once they are confirmed in backup storage. Zero 1.9 can't read these paths, so rolling back to 1.9 with v5 backups enabled resyncs the replica. (#6368, #6394)

Fixes

Queries and Connections

  • Large query results are now sent in parts of about 1 MiB of row data. 1.10 clients receive them as binary chunks from 1.10 and later servers; older clients keep the JSON format. (#6328)
  • Complex queries with relationships, OR, limit(), and optimistic updates no longer miss changes or show stale rows. (#6380, #6381)
  • The Inspector and Analyze Query CLI now show zero-cache errors and support server-side NOT EXISTS. Client-side execution remains unsupported. (#6447)
  • Stalled WebSocket sends now fail after ten seconds, and concurrent first connections to a new client group no longer conflict. (#6329, #6389)

Replication and Backfills

  • Postgres NOT NULL changes no longer rebuild SQLite tables. Failed initial sync no longer leaves a replication slot retaining WAL. (#6309, #6335)
  • Backfills no longer pause or stop during long copies. Supabase publication hooks include existing rows, large backfills share write time with the replica, and later writes are recognized. (#6439, #6440, #6453, #6454, #6459)
  • Lag metrics no longer spike after restart or grow for unaffected client groups. (#6279, #6367)
  • Replication recovers from stalled database work, and concurrent operations use separate Postgres connections. (#6419, #6445)

Backups and Startup

  • Legacy backups now handle WAL resets, large database files, and temporary invalid backup metadata. (#6359, #6428, #6425)
  • Large replicas skip a potentially long, full SQLite optimization when starting after a schema change. (#6426)
  • Failed initial sync no longer leaves a partial replica that blocks backup restore. Shutdown errors preserve the current replica for validation after restart. (#6427, #6452)

Breaking Changes

Although these are technically breaking changes, we think they are unlikely to affect any real apps:

  • If you use {scalar: true}, the subquery must match every column of a primary or declared unique key using equality. Otherwise, remove the hint or declare a unique key. (#6307)
  • If you set ZERO_CHANGE_STREAMER_FLOW_CONTROL_CONSENSUS_PADDING_SECONDS, replace it with ZERO_CHANGE_STREAMER_FLOW_CONTROL_CONSENSUS_TIMEOUT_PROPORTION. The new value is a ratio, not seconds. Slow serving replicas now restart after 30 seconds by default; set ZERO_CHANGE_STREAMER_FLOW_CONTROL_SLOW_SUBSCRIBER_GRACE_PERIOD_SECONDS=0 to disable this. (#6357, #6358)
  • If your database limits connections, allow at least five ChangeDB connections plus one per view-syncer. ZERO_CHANGE_MAX_CONNS no longer limits this usage. See Change DB. (#6445)