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.
WarningThe 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.
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');
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 |
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"}
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}`); } }), });
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), }); } }), });
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, }), }); }), });