SurrealDB
SurrealDB Docs Logo

Enter a search query

Navigation

Concepts

Diagnostics

Diagnostics

The Diagnostics API allows you to wrap engines and intercept protocol-level communication between the SDK and SurrealDB. This is useful for debugging queries, analyzing SDK behavior, 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.

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:

PropertyTypeDescription
typestringThe type of operation (e.g. "open", "query", "signin")
keystringA stable UUID that links related before and after phases
phasestringWhen the event fires: "before", "progress", or "after"

Events in the after phase include additional properties:

PropertyTypeDescription
durationstringHow long the operation took
successbooleanWhether the operation succeeded
resultunknownThe 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.

{"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":"test","database":"test"}}} {"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.

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.

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 centralized observability.

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