Skip to content

Live Queries

Live queries allow the server to push updates to clients whenever the underlying data changes, using resource-based invalidation and JSON diff-patching.

  1. A query is marked as @live in the schema
  2. The server tracks which resource identifiers the query accesses
  3. When a mutation invalidates one of those identifiers, the query re-executes
  4. Only the diff is sent to the client via jsondiffpatch

Add the @live directive to query fields in your schema:

type Query {
users: [User!]! @live
}

From within a resolver, use the liveQueryStore from context:

const resolvers = {
Mutation: {
createUser: async (_, args, context) => {
const user = await db.createUser(args)
await context.liveQueryStore.invalidate('Query.users')
return user
},
},
}

The invalidate function accepts multiple formats:

// Simple string
liveQueryStore.invalidate('Query.users')
// Multiple identifiers
liveQueryStore.invalidate(['Query.users', 'Query.userCount'])
// Builder function
liveQueryStore.invalidate((tools) => [
tools.id('User', user.id),
tools.args('Query.user', { id: user.id }),
])

Use @liveIdentifier on arguments to automatically scope live query subscriptions:

type Query {
user(id: ID! @liveIdentifier): User @live
}

For multi-instance deployments, pass redisUrl to share invalidations across servers:

createServer({
liveQueryStore: {
redisUrl: 'redis://localhost:6379',
redisChannel: 'my-app-live-queries',
},
})