Skip to main content

Observability

vectlite ships with two complementary observability features:

  1. search_with_stats() — per-call timings, candidate counts, fusion strategy, and explain payloads for individual searches.
  2. OpenTelemetry tracing — span-based instrumentation that integrates with your existing OTel collector / backend.

The OpenTelemetry SDK is loaded lazily and is not a runtime dependency. Install it only if you want tracing.

OpenTelemetry

Setup (Python)

pip install opentelemetry-api opentelemetry-sdk
import vectlite

# Auto-detect: uses the default tracer from opentelemetry.trace if installed
vectlite.configure_opentelemetry()

# Or supply your own tracer
vectlite.configure_opentelemetry({"tracer": my_tracer})

# Custom tracer name (default: "vectlite")
vectlite.configure_opentelemetry({"tracer_name": "my-app"})

# Disable
vectlite.configure_opentelemetry(False)

Setup (Node.js)

npm install @opentelemetry/api @opentelemetry/sdk-node
const vectlite = require('vectlite')

vectlite.configureOpenTelemetry() // auto-detect
vectlite.configureOpenTelemetry({ tracer: myTracer }) // explicit tracer
vectlite.configureOpenTelemetry({ tracerName: 'my-app' }) // rename
vectlite.configureOpenTelemetry({ enabled: false }) // disable

What gets traced

Each search_text() and search_text_with_stats() call creates a vectlite.search span with:

AttributeDescription
db.systemAlways "vectlite"
db.operation.nameAlways "search"
vectlite.search.kRequested result count
vectlite.search.namespaceTarget namespace
vectlite.search.has_denseWhether a dense query vector was provided
vectlite.search.has_sparseWhether sparse terms were provided
vectlite.search.fusionFusion strategy ("linear" or "rrf")
vectlite.search.used_annWhether HNSW was used (set after completion)
vectlite.search.result_countNumber of results returned
vectlite.search.total_usTotal search time in microseconds

If a search raises, the span records the exception and sets an error status before re-raising.

Search diagnostics

For per-call inspection (without standing up an OTel pipeline), use search_with_stats():

Python

outcome = db.search_with_stats(query, k=5, sparse=terms, explain=True)

print(outcome["stats"]["timings"]) # {"dense_us": 120, "sparse_us": 45, ...}
print(outcome["stats"]["used_ann"]) # True
print(outcome["results"][0]["explain"]) # detailed scoring breakdown

Node.js

const outcome = db.searchWithStats(query, { k: 5, sparse: terms, explain: true })

console.log(outcome.stats.timings)
console.log(outcome.stats.used_ann)
console.log(outcome.results[0].explain)

See the Diagnostics guide for the full SearchStats reference.

  • Local dev / quick checkssearch_with_stats() with explain=True.
  • Production aggregate metrics → OpenTelemetry, exported to your backend (Tempo, Jaeger, Honeycomb, Datadog, etc.).
  • One-off perf investigation → both. OTel gives the trend; search_with_stats gives the per-call breakdown.