# Live queries

Subscribe to real-time changes from SurrealDB over a WebSocket connection with version 2 of the PHP SDK.

Live queries notify your application whenever records that match a query are created, updated, or deleted. You start a `LIVE SELECT` statement to get a query ID, then iterate the messages the server pushes for that ID.

> [!NOTE]
> Live queries require a WebSocket connection. They are not available over HTTP. Check support with [`isFeatureSupported()`](/docs/reference/php/v2/concepts/connecting-to-surrealdb.md#testing-for-features) before relying on one.

## Starting a live query

Run a [`LIVE SELECT`](/docs/reference/query-language/statements/live-select.md) statement with `run()`. The result is the live query ID.

```php
[$queryId] = $db->run('LIVE SELECT * FROM person');
```

## Receiving messages

Pass the ID to `live()`. It returns an iterable of [`LiveMessage`](/docs/reference/php/v2/api/core.md#livemessage) objects, one per change. Each message carries the `action`, the affected `record` ID, and the new `value`.

```php
use SurrealDB\SDK\Live\LiveAction;

foreach ($db->live($queryId) as $message) {
    match ($message->action) {
        LiveAction::Create => handleCreate($message->value),
        LiveAction::Update => handleUpdate($message->value),
        LiveAction::Delete => handleDelete($message->record),
        LiveAction::Killed => break,
    };
}
```

## Running without blocking the application

A `foreach` over `live()` blocks the current PHP process while it waits for the next message. The standard PHP runtime (PHP-FPM or the CLI) handles one task per worker, so a process parked on a live query cannot serve anything else.

> [!WARNING]
> Consume live queries in a dedicated, long-running worker, and run the PHP runtime with several workers so that one worker blocked on a live query does not freeze the rest of your application. Avoid opening a live query inside a normal web request.

To run live queries alongside the rest of your application, choose an asynchronous runtime or run dedicated workers. See [Runtimes and workers](/docs/reference/php/v2/concepts/runtimes.md) for configuring PHP-FPM with dedicated workers, OpenSwoole, and FrankenPHP.

## Live actions

Every message has an action from the `LiveAction` enum:

| Action | Description |
|--------|-------------|
| `LiveAction::Create` | A new record matched the query |
| `LiveAction::Update` | A matching record was modified |
| `LiveAction::Delete` | A matching record was removed |
| `LiveAction::Killed` | The live query was stopped on the server |

## Stopping a live query

Stop a live query by running a [`KILL`](/docs/reference/query-language/statements/kill.md) statement with its ID. The loop receives a final `LiveAction::Killed` message and ends.

```php
$db->run('KILL $id', ['id' => $queryId]);
```

## Learn more

- [Surreal API reference](/docs/reference/php/v2/api/core.md#live) for the `live()` signature
- [LIVE SELECT](/docs/reference/query-language/statements/live-select.md) for the SurrealQL syntax
- [Connecting to SurrealDB](/docs/reference/php/v2/concepts/connecting-to-surrealdb.md) for WebSocket setup
