# Live queries

Subscribe to real-time changes with live queries in the SurrealDB Kotlin SDK.

[Live queries](/docs/reference/query-language/statements/live-select.md) push changes to your application as records are created, updated, or deleted. In the Kotlin SDK, a live subscription exposes a coroutine [`Flow`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/) of notifications that you collect.

> [!NOTE]
> Live queries require a stateful connection and are only available over the **WebSocket** transport. Calling [`.live()`](/docs/reference/kotlin/api/core/surreal-client.md#live) over HTTP throws [`SurrealFeatureNotSupportedException`](/docs/reference/kotlin/api/errors.md). Check support with [`client.supports(SurrealFeature.LiveQueries)`](/docs/reference/kotlin/api/core/surreal-client.md#supports).

## API references

<table>
	<thead>
		<tr>
			<th scope="col">Method</th>
			<th scope="col">Description</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/kotlin/api/core/surreal-client.md#live"><code>client.live(table)</code></a></td>
			<td scope="row" data-label="Description">Starts a live query and returns a subscription</td>
		</tr>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/kotlin/api/core/live-subscription.md#events"><code>subscription.events</code></a></td>
			<td scope="row" data-label="Description">A <code>Flow</code> of live notifications</td>
		</tr>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/kotlin/api/core/live-subscription.md#cancel"><code>subscription.cancel()</code></a></td>
			<td scope="row" data-label="Description">Stops the subscription</td>
		</tr>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/kotlin/api/core/surreal-client.md#kill"><code>client.kill(id)</code></a></td>
			<td scope="row" data-label="Description">Kills a live query by ID</td>
		</tr>
	</tbody>
</table>

## Starting a live query

Call [`.live()`](/docs/reference/kotlin/api/core/surreal-client.md#live) with a table name to receive a [`LiveQuerySubscription`](/docs/reference/kotlin/api/core/live-subscription.md), then collect its [`events`](/docs/reference/kotlin/api/core/live-subscription.md#events) flow. Each [`SurrealLiveNotification`](/docs/reference/kotlin/api/core/live-subscription.md#notification) carries an `action` (`"CREATE"`, `"UPDATE"`, or `"DELETE"`) and a `result` payload.

```kotlin
import com.surrealdb.kotlin.SurrealFeature
import kotlinx.coroutines.launch

if (client.supports(SurrealFeature.LiveQueries)) {
    val subscription = client.live("person")

    val job = scope.launch {
        subscription.events.collect { event ->
            println("${event.action}: ${event.result}")
        }
    }
}
```

Pass `diff = true` to receive [JSON Patch](https://jsonpatch.com/) diffs instead of the full record.

```kotlin
val subscription = client.live("person", diff = true)
```

## Filtered live queries

To watch a subset of records with a `WHERE` clause, run a `LIVE SELECT` statement through [`.query()`](/docs/reference/kotlin/concepts/executing-queries.md); the result is the live query UUID, which you can later pass to [`.kill()`](/docs/reference/kotlin/api/core/surreal-client.md#kill).

```kotlin
val liveId = client.query("LIVE SELECT * FROM person WHERE age >= 18")
```

## Stopping a subscription

Cancel a subscription started with [`.live()`](/docs/reference/kotlin/api/core/surreal-client.md#live) by calling [`.cancel()`](/docs/reference/kotlin/api/core/live-subscription.md#cancel), which also kills the underlying live query on the server. Cancel the collecting coroutine separately.

```kotlin
subscription.cancel()
job.cancel()
```

For live queries started via raw SurrealQL, kill them with their UUID.

```kotlin
client.kill(liveId.toString())
```

## Learn more

- [Live subscription reference](/docs/reference/kotlin/api/core/live-subscription.md) for the subscription and notification types
- [SurrealClient API reference](/docs/reference/kotlin/api/core/surreal-client.md) for `.live()` and `.kill()`
- [Features and events](/docs/reference/kotlin/api/features.md) for checking transport support
- [LIVE SELECT](/docs/reference/query-language/statements/live-select.md) for the SurrealQL statement
