# Diagnostics

The JavaScript SDK provides a diagnostics API for intercepting and inspecting protocol-level communication with SurrealDB.

The Diagnostics API allows you to wrap engines and intercept protocol-level communication between the SDK and SurrealDB. This is useful for debugging queries, analysing SDK behaviour, measuring operation timings, and building custom logging or monitoring tools.

Since the API is implemented as an engine wrapper, it adds no overhead to the SDK unless you explicitly enable it.

> [!WARNING]
> The diagnostics events are considered unstable and may change between SDK versions. Avoid relying on this API in production environments as it may negatively affect performance.

## Wrapping engines with diagnostics

Use the `applyDiagnostics` function to wrap your engines with a diagnostic listener. The listener function is called for every protocol-level event.

```ts
import { Surreal, createRemoteEngines, applyDiagnostics } from 'surrealdb';

const db = new Surreal({
    engines: applyDiagnostics(createRemoteEngines(), (event) => {
        console.log(event);
    }),
});

await db.connect('ws://localhost:8000');
```

## Understanding diagnostic events

Each diagnostic event is a plain object with at least three properties:

| Property | Type | Description |
|----------|------|-------------|
| `type` | `string` | The type of operation (e.g. `"open"`, `"query"`, `"signin"`) |
| `key` | `string` | A stable UUID that links related `before` and `after` phases |
| `phase` | `string` | When the event fires: `"before"`, `"progress"`, or `"after"` |

Events in the `after` phase include additional properties:

| Property | Type | Description |
|----------|------|-------------|
| `duration` | `string` | How long the operation took |
| `success` | `boolean` | Whether the operation succeeded |
| `result` | `unknown` | The result or error details |

## Example diagnostic output

The following is an example of the diagnostic events produced during a typical connection, authentication, and query sequence.

```json
{"type":"open","key":"1560a0e1-...","phase":"before"}
{"type":"open","key":"1560a0e1-...","phase":"after","success":true,"duration":"535us"}

{"type":"version","key":"5c9bda29-...","phase":"before"}
{"type":"version","key":"5c9bda29-...","phase":"after","success":true,"duration":"964us","result":{"version":"surrealdb-2.1.0"}}

{"type":"use","key":"4fba2fe5-...","phase":"before"}
{"type":"use","key":"4fba2fe5-...","phase":"after","success":true,"duration":"387us","result":{"requested":{"namespace":"main","database":"main"}}}

{"type":"signin","key":"d61ab7cf-...","phase":"before"}
{"type":"signin","key":"d61ab7cf-...","phase":"after","success":true,"duration":"14ms","result":{"variant":"system_user"}}

{"type":"query","key":"6763817d-...","phase":"before"}
{"type":"query","key":"6763817d-...","phase":"progress","result":{"query":"CREATE ONLY $bind__4 CONTENT $bind__5","params":{"bind__4":"person:1","bind__5":{"firstname":"John","lastname":"Doe"}}}}
{"type":"query","key":"6763817d-...","phase":"after","success":true,"duration":"1ms"}
```

## Use cases

### Debugging queries

Log all queries with their bound parameters and execution times to understand what the SDK sends to the database.

```ts
const db = new Surreal({
    engines: applyDiagnostics(createRemoteEngines(), (event) => {
        if (event.type === 'query' && event.phase === 'after') {
            console.log(`Query completed in ${event.duration}, success: ${event.success}`);
        }
    }),
});
```

### Performance monitoring

Collect timing data for all operations to identify slow queries or connection bottlenecks.

```ts
const timings: Record<string, string>[] = [];

const db = new Surreal({
    engines: applyDiagnostics(createRemoteEngines(), (event) => {
        if (event.phase === 'after') {
            timings.push({
                type: event.type,
                duration: event.duration,
                success: String(event.success),
            });
        }
    }),
});
```

### Custom logging

Forward diagnostic events to your application's logging infrastructure for centralised observability.

```ts
const db = new Surreal({
    engines: applyDiagnostics(createRemoteEngines(), (event) => {
        logger.debug('SurrealDB', {
            type: event.type,
            phase: event.phase,
            key: event.key,
            ...(event.phase === 'after' && {
                duration: event.duration,
                success: event.success,
            }),
        });
    }),
});
```

## Learn more

- [Connecting to SurrealDB](/docs/reference/javascript/concepts/connecting-to-surrealdb.md) for engine configuration
- [Error handling](/docs/reference/javascript/concepts/error-handling.md) for handling SDK errors
