Live queries allow your application to receive real-time notifications whenever records in the database are created, updated, or deleted. The JavaScript SDK provides two approaches: managed live queries that the SDK controls and automatically restarts on reconnect, and unmanaged live queries that you create via SurrealQL and subscribe to manually.
NoteLive queries require a WebSocket connection. They are not supported over HTTP. You can check for support using the feature testing mechanism.
| Method | Description |
|---|---|
db.live(target) | Creates a managed live query subscription |
db.liveOf(id) | Subscribes to an existing live query by its ID |
live.subscribe(callback) | Registers a callback for live query updates |
live.kill() | Stops the live query and unsubscribes all listeners |
The .live() method creates a managed live query subscription. The SDK handles the lifecycle of the query, including automatically restarting it when the connection reconnects. The provided Table determines the records to listen to.
import { Table } from 'surrealdb'; const live = await db.live(new Table('users'));
Much like the .select() method, you can chain multiple methods to configure the live query before executing it. This includes enabling diff results, selecting specific fields, and filtering the records to listen to.
import { gt } from 'surrealdb'; const live = await db.live(new Table('users')) .diff() .fields('name', 'email', 'age') .where(gt('age', 18));
Use .subscribe() on the returned live query to register a callback. The callback receives the action, the result record, and the record ID.
live.subscribe((action, result, record) => { switch (action) { case 'CREATE': console.log('New user:', result); break; case 'UPDATE': console.log('Updated user:', record, result); break; case 'DELETE': console.log('Deleted user:', record); break; } });
Live queries also support the for await...of pattern, which yields each message as an object with action and value properties.
for await (const { action, value } of live) { console.log(`${action}:`, value); }
If you need to start a live query using SurrealQL (for example, with a custom WHERE clause), you can execute a LIVE SELECT statement and then subscribe to it using .liveOf(). Unmanaged queries are not automatically restarted on reconnect.
const [id] = await db.query('LIVE SELECT * FROM users WHERE active = true'); const live = db.liveOf(id); live.subscribe((action, result, record) => { console.log(action, result); });
Every live query message has an action that indicates what happened to the record:
| Action | Description |
|---|---|
CREATE | A new record was created that matches the subscription |
UPDATE | An existing record within the subscription was modified |
DELETE | A record within the subscription was deleted |
Call .kill() to stop a live query and unsubscribe all listeners. This releases resources on both the client and the server.
await live.kill();
Managed live queries created with .live() are automatically restarted when the SDK reconnects to the database after a connection drop. This means your application will continue receiving updates without any manual intervention.
Unmanaged live queries created via LIVE SELECT and .liveOf() are not automatically restarted. If you need reconnection resilience with custom queries, prefer using a managed live query or re-subscribing manually by listening to the connected event.
Live queries require a WebSocket-based engine. Before creating a live query, you can verify that the current connection supports them.
import { Features } from 'surrealdb'; if (db.isFeatureSupported(Features.LiveQueries)) { const live = await db.live(new Table('users')); }