client.query(), you subscribe once — the server re-executes the query and pushes a new result every time a matching CRDT changes.
How it works
- Client sends
SubscribeQueryover the existing WebSocket connection with a query spec and aquery_id. - Server executes the query immediately and pushes a first
QueryResultframe. - Whenever a CRDT in the namespace changes, the server checks all active live query subscriptions. Queries whose
fromglob matches the changed CRDT (and whose optionaltypefilter matches) are re-executed, and a newQueryResultis pushed. - Client sends
UnsubscribeQueryto cancel. The server also cleans up automatically on disconnect.
SDK — client.liveQuery()
LiveQueryHandle
LiveQueryResult
React — useLiveQuery()
data on every push, and unsubscribes on unmount. loading is true until the first result arrives.
Supported query specs
Live Queries accept the same spec asclient.query():
See the aggregation table for supported operations per CRDT type.
Performance notes
Type filter skips unrelated deltas. When you settype: "gcounter", the server skips re-execution entirely when an ORSet or LwwRegister changes — even if the glob pattern would match the key. Always set type when your pattern is cross-type.
SubscribeQuery frames automatically after a WebSocket reconnect. No manual re-subscription is needed.
Multiple handles per spec. Each liveQuery() call creates an independent subscription with its own query_id. If you need multiple listeners on the same query, use handle.onResult() multiple times on a single handle instead of calling liveQuery() twice.