Skip to content

Operation Telemetry Reference ​

Operation telemetry lets you ask OpenViking to return a compact summary of what happened during a request, such as duration, token usage, vector retrieval activity, queue progress, and resource-processing stages.

Use it when you want to:

  • debug a slow or unexpected request
  • inspect token or retrieval behavior
  • capture structured execution data in your own logs or observability pipeline

For the broader observability entry points, including health checks, ov tui, and Web Studio, see Observability & Diagnostics.

How it works ​

Telemetry is opt-in. OpenViking only returns a top-level telemetry object when you request it.

Typical response shape:

json
{
  "status": "ok",
  "result": {"...": "..."},
  "telemetry": {
    "id": "tm_xxx",
    "summary": {
      "operation": "search.find",
      "status": "ok",
      "duration_ms": 31.2,
      "tokens": {
        "total": 24,
        "llm": {
          "input": 12,
          "output": 6,
          "total": 18
        }
      },
      "vector": {
        "searches": 3,
        "scored": 26,
        "passed": 8,
        "returned": 5
      }
    }
  }
}

Notes:

  • telemetry.id is an opaque correlation id
  • telemetry.summary is the structured payload intended for users
  • summary groups appear only when the operation produced them
  • numeric zero values in optional groups are generally omitted; the cuVS memory estimates retain zero values

Supported operations ​

HTTP API ​

Operation telemetry is currently available on these endpoints:

  • POST /api/v1/search/find
  • POST /api/v1/search/search
  • POST /api/v1/resources/temp_upload
  • POST /api/v1/resources
  • POST /api/v1/skills
  • POST /api/v1/sessions
  • POST /api/v1/sessions/{session_id}/messages
  • POST /api/v1/sessions/{session_id}/commit
  • POST /api/v1/sessions/{session_id}/messages/batch
  • PATCH /api/v1/sessions/{session_id}/config
  • POST /api/v1/content/write
  • POST /api/v1/content/batch-write
  • POST /api/v1/content/set_tags
  • POST /api/v1/skills/find
  • PUT /api/v1/skills/{skill_name}

Python SDK ​

The Python clients can request telemetry for the following operations. High-level return values do not necessarily expose the top-level HTTP telemetry object; see the Python example below:

  • add_resource(...)
  • add_skill(...)
  • find(...)
  • search(...)
  • create_session(...)
  • add_message(...)
  • commit_session(...)
  • Session.commit(...)

Requesting telemetry ​

JSON APIs ​

For JSON request bodies, telemetry supports these forms:

json
{"telemetry": true}
json
{"telemetry": {"summary": true}}

true and {"summary": true} both request the same payload: telemetry.id + telemetry.summary.

The object form currently exposes the summary switch only.

If you do not want telemetry, either omit the field or set:

json
{"telemetry": false}
json
{"telemetry": {"summary": false}}

Multipart upload API ​

POST /api/v1/resources/temp_upload is a multipart form endpoint. For this endpoint, pass telemetry as a form field:

bash
curl -X POST http://localhost:1933/api/v1/resources/temp_upload \
  -H "X-API-Key: your-key" \
  -F "file=@./notes.md" \
  -F "telemetry=true"

This endpoint currently accepts the boolean form only. upload_mode is also a form field for this endpoint; it defaults to local and should only be set to shared when you explicitly need distributed shared temporary uploads. Python HTTP clients can alternatively set upload.mode = "shared" in ovcli.conf; the Rust ov CLI uses OPENVIKING_UPLOAD_MODE=shared instead.

Common summary groups ​

The top-level summary always includes:

  • operation
  • status
  • duration_ms

Depending on the operation, you may also see these groups:

  • tokens: LLM and embedding token totals
  • vector: vector search and filtering counts
  • resource: resource ingestion and processing stages
  • queue: queue processing counts for wait-mode imports
  • semantic_nodes: semantic extraction totals
  • memory: memory extraction or dedup summaries
  • errors: aggregated error information

If a group does not apply to the operation, it is omitted.

Field reference ​

Only fields that are actually produced by an operation are returned. Missing groups may be inapplicable, uncollected, or pruned because their numeric values are zero. Do not interpret absence as a measured zero or as proof that a stage ran.

Top-level telemetry fields ​

FieldMeaning
telemetry.idOpaque correlation id for this operation
summary.operationOperation name, such as search.find, resources.add_resource, or session.commit
summary.statusFinal telemetry status, usually ok or error
summary.duration_msEnd-to-end duration of the operation in milliseconds

summary.tokens ​

FieldMeaning
summary.tokens.totalTotal tokens counted for this operation
summary.tokens.llm.inputTotal LLM input tokens
summary.tokens.llm.outputTotal LLM output tokens
summary.tokens.llm.totalTotal LLM tokens
summary.tokens.embedding.totalTotal embedding-model tokens

summary.vector ​

FieldMeaning
summary.vector.searchesNumber of vector search calls
summary.vector.scoredNumber of candidates that were scored
summary.vector.passedNumber of candidates that passed thresholding or later filters
summary.vector.returnedNumber of results returned to upper-layer logic
summary.vector.scannedNumber of vectors scanned by the backend
summary.vector.scan_reasonText description of the scan strategy or reason

When cuVS is configured, summary.vector.cuvs aggregates routing and timing information across every dense search in the operation. The aggregation is independent of concurrent-query completion order. It never includes the query vector, filter values, or URI contents, and unknown dimension values are coalesced into the bounded other bucket.

FieldMeaning
summary.vector.cuvs.searchesNumber of dense searches represented by this aggregate
summary.vector.cuvs.algorithms.<algorithm>Search count by cuVS algorithm, such as brute_force or cagra
summary.vector.cuvs.dtypes.<dtype>Search count by GPU dataset/query dtype, float32 or float16
summary.vector.cuvs.max_concurrent_gpu_searchesMaximum configured per-index in-flight GPU search limit observed
summary.vector.cuvs.auto_mode_searchesNumber of searches with automatic CPU/GPU routing enabled
summary.vector.cuvs.micro_batching_searchesNumber of searches that used the opt-in OpenViking micro-batch scheduler
summary.vector.cuvs.micro_batched_searchesNumber of those searches dispatched with more than one query row
summary.vector.cuvs.micro_batching_warm_fast_path_searchesNumber of micro-batching-scheduler searches enqueued from a clean current snapshot without caller-side device-gate admission
summary.vector.cuvs.batch_size_maxMaximum query-row count observed in one shared cuVS call
summary.vector.cuvs.searches_by_batch_size.<size>Search count by bounded batch size from 1 through 8
summary.vector.cuvs.routes.<reason>Search count by route, such as cuvs, native_filter_threshold, native_rebuild_pending, or native_memory_budget
summary.vector.cuvs.filter_kinds.<kind>Search count by low-cardinality filter class: none, scalar, or path
summary.vector.cuvs.filter_cache_hitsNumber of searches that reused a prepared or preflight filter
summary.vector.cuvs.native_filter_reusesNumber of native recalls that reused the preflight bitmap
summary.vector.cuvs.buildsNumber of searches that performed a GPU index build
summary.vector.cuvs.eligible_count_maxMaximum candidate count observed after native filtering
summary.vector.cuvs.records_generation_maxMaximum record generation observed
summary.vector.cuvs.index_size_maxMaximum cuVS host-snapshot size observed
summary.vector.cuvs.memory.estimated_peak_bytes_maxMaximum estimated peak bytes used for auto-build admission
summary.vector.cuvs.memory.free_bytes_minMinimum free device bytes observed inside the per-GPU admission coordinator
summary.vector.cuvs.memory.usable_bytes_minMinimum free bytes observed after applying the configured reserve
summary.vector.cuvs.timings_ms.<stage>.sumSum across searches for total, preflight, queue, gpu_gate_queue, build, filter_prepare, batch_wait, gpu_search, or native_search
summary.vector.cuvs.timings_ms.<stage>.maxMaximum single-search time for the same stage

For a shared micro-batch, gpu_search is the cuVS call's service latency from each member request's perspective. Its duration is therefore recorded once per request: gpu_search.sum is useful as aggregate request latency, but it is not GPU busy time and can be approximately batch-size times the physical call duration. batch_wait is the request's time from scheduler enqueue to GPU dispatch, including worker scheduling and any wait behind current device work. gpu_gate_queue is caller-side time waiting to enter the serialized device gate before gated rebuild/filter preparation, enqueue, or a non-batched GPU search. A warm-fast-path request bypasses that caller admission, so its gpu_gate_queue is zero; its worker-side wait remains part of batch_wait. The broader queue stage includes both forms of request-visible queueing when they apply.

summary.resource ​

This group appears on resource ingestion operations such as resources.add_resource.

FieldMeaning
summary.resource.total.duration_msTotal duration of the add-resource operation
summary.resource.source_execute.duration_msTime spent executing the source operation
summary.resource.source_prepare.duration_msTime spent preparing a durable source
summary.resource.parse_artifact.duration_msTime spent producing the parser artifact
summary.resource.target_resolve.duration_msTime spent resolving the final resource target
summary.resource.update_plan.duration_msTotal time spent building the incremental update plan
summary.resource.update_plan.artifact_inventory.duration_msTime spent scanning and normalizing the parser artifact
summary.resource.update_plan.rnfv_snapshot.duration_msTime spent reading the R/N/F/V snapshot
summary.resource.update_plan.diff_and_compile.duration_msTime spent resolving the diff and compiling actions
summary.resource.content_commit.duration_msTime spent applying content actions to the formal tree
summary.resource.derived_enqueue.duration_msTime spent enqueueing semantic and index work
summary.resource.semantic.queue_wait.duration_msTime semantic work spent waiting in QueueFS
summary.resource.semantic.execute.duration_msTime spent executing semantic work
summary.resource.embedding.queue_wait.duration_msTime embedding work spent waiting in QueueFS
summary.resource.embedding.execute.duration_msTime spent executing embedding work
summary.resource.flags.waitWhether the request used wait=true
summary.resource.flags.build_indexWhether the request enabled build_index
summary.resource.flags.summarizeWhether the request explicitly enabled summarize
summary.resource.flags.watch_enabledWhether watch management was enabled for this request

summary.queue ​

This group appears when OpenViking waits for queue-backed work to complete.

FieldMeaning
summary.queue.semantic.processedNumber of semantic-queue messages processed
summary.queue.semantic.requeue_countNumber of semantic messages re-enqueued for retry
summary.queue.semantic.error_countNumber of semantic-queue errors
summary.queue.embedding.processedNumber of embedding-queue messages processed
summary.queue.embedding.requeue_countNumber of embedding messages re-enqueued for retry
summary.queue.embedding.error_countNumber of embedding-queue errors

summary.semantic_nodes ​

FieldMeaning
summary.semantic_nodes.totalTotal semantic-tree node count
summary.semantic_nodes.doneNumber of completed nodes
summary.semantic_nodes.pendingNumber of pending nodes
summary.semantic_nodes.runningNumber of nodes still running

summary.memory ​

This group describes collected memory-extraction metrics. The current commit response covers the synchronous archive/submission phase; background extraction can finish later. Legacy stage names below appear only if a code path records them; they are not a fixed sequence that every V3 extraction follows.

FieldMeaning
summary.memory.extractedFinal number of memories extracted by the operation
summary.memory.extract.duration_msTotal duration of the memory-extraction flow
summary.memory.extract.candidates.totalCurrent V3 count: newly written URIs plus edited URIs, rather than all proposed candidates
summary.memory.extract.candidates.standardStandard memory candidates
summary.memory.extract.actions.createdNumber of newly created memories
summary.memory.extract.actions.mergedNumber of merges into existing memories
summary.memory.extract.actions.deletedNumber of deleted old memories
summary.memory.extract.actions.skippedNumber of skipped operations
summary.memory.extract.actions.failedNumber of recorded extraction errors
summary.memory.extract.actions_by_typeAction counts grouped by memory type
summary.memory.extract.stages.prepare_inputs_msTime spent preparing extraction inputs
summary.memory.extract.stages.llm_extract_msTime spent in the LLM extraction call
summary.memory.extract.stages.normalize_candidates_msTime spent parsing and normalizing candidates
summary.memory.extract.stages.profile_create_msTime spent creating or updating profile memory
summary.memory.extract.stages.dedup_msTime spent deduplicating candidates
summary.memory.extract.stages.create_memory_msTime spent creating new memories
summary.memory.extract.stages.merge_existing_msTime spent merging into existing memories
summary.memory.extract.stages.delete_existing_msTime spent deleting older memories
summary.memory.extract.stages.flush_semantic_msTime spent flushing semantic queue work
FieldMeaning
summary.search.target_abstract.duration_msTime spent prefetching abstracts for target URIs
summary.search.intent_analysis.duration_msTime spent analyzing query intent
summary.search.embed_query.duration_msTime spent embedding the query
summary.search.vector_retrieval.duration_msTime spent in vector retrieval
summary.search.typed_queries_countNumber of typed queries produced during planning

summary.errors ​

FieldMeaning
summary.errors.stageLogical stage where the error was recorded
summary.errors.error_codeError code or exception type
summary.errors.messageHuman-readable error message

Examples ​

Search request with telemetry ​

bash
curl -X POST http://localhost:1933/api/v1/search/find \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-key" \
  -d '{
    "query": "memory dedup",
    "limit": 5,
    "telemetry": true
  }'

Add a resource and return telemetry ​

bash
curl -X POST http://localhost:1933/api/v1/resources \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-key" \
  -d '{
    "path": "https://raw.githubusercontent.com/volcengine/OpenViking/main/README.md",
    "wait": true,
    "timeout": 120,
    "reason": "telemetry demo",
    "telemetry": true
  }'

Python: read the complete HTTP response ​

The SDK can send options={"telemetry": True}, but current high-level methods such as find() return only result, discarding the top-level telemetry object. Use an HTTP request when your application needs the summary:

python
import httpx

with httpx.Client(base_url="http://localhost:1933", timeout=30) as client:
    response = client.post(
        "/api/v1/search/find",
        headers={"X-API-Key": "your-user-key"},
        json={"query": "memory dedup", "limit": 5, "telemetry": True},
    )
    response.raise_for_status()
    payload = response.json()
    print(payload["telemetry"]["summary"])

Limitations and behavior ​

  • OpenViking currently exposes summary-only telemetry to users
  • {"telemetry": {"events": true}} is not a supported public request shape
  • event-stream style selection is not part of the public API
  • Current session.commit has no wait parameter. Its response telemetry covers archiving/submission, not the eventual completion of background extraction. Poll the returned task ID when present; see Sessions.
  • A resource import with wait=false may also finish after response telemetry is returned. Use wait mode when the summary should include processing completed within the request.
  • telemetry shape is stable at the top level, but optional summary groups vary by operation

Open source under the AGPL-3.0 License. Font licenses