VeltrixDB Docs
v1.16 GitHub FAQ Quickstart

Monitoring & Observability

VeltrixDB exposes a Prometheus scrape endpoint (about 85 veltrixdb_* metric families), liveness/readiness probes, a slow-trace endpoint and a web dashboard, all on the same admin HTTP port.

Endpoints

curl http://localhost:2112/metrics   # Prometheus scrape endpoint
curl http://localhost:2112/healthz   # liveness probe ("ok")
curl http://localhost:2112/readyz    # readiness probe ("ready" / 503)
curl http://localhost:2112/traces    # recent sampled + slow (≥ 50 ms) spans, NDJSON
open http://localhost:2112/admin/ui  # web dashboard (loopback-only unless -admin-token)

All of these are served on the admin/metrics port (-metrics-addr, :2112 by default), separate from the client data port (9000 by default). /metrics, /healthz and /readyz are never authenticated. /readyz answers 503 initializing until the engine is open and 503 degraded: disks [N] failed when a disk breaker has tripped; it does not wait for WAL replay or the search-index rebuild — check INFO for search_ready=1 before sending searches to a restarted node.

On v1.16 and earlier only veltrixdb_* series are exported. The server registers its own collector on a private registry: there are no go_* runtime or process_* metrics, and the runtime / process / system / disk collector in metrics/hardware.go is not registered either. Get process and host metrics from node-exporter or a process exporter. Search and raft have no Prometheus metrics; search state is in INFO (search_ready, search_loaded=x/y), raft state in /admin/cluster, and both in the logs.
New on main after v1.16 — ships in the next release /metrics also serves go_* and process_* (labelled node; process_* reads /proc, so it is Linux only — macOS serves only process_start_time_seconds), the hardware collector the Grafana dashboards read (veltrixdb_runtime_*, _process_*, _system_*, _disk_*; the last three Linux only), and the search, raft and replication-recovery series below. A scrape of a fresh node takes about 8 ms.

Key metrics to watch

All metric families carry a node label (per-disk ones add disk). The core set to alert on:

MetricHealthy value
veltrixdb_storage_writes_total / veltrixdb_storage_reads_totalGrowing under load
veltrixdb_cache_hits_total / veltrixdb_cache_misses_totalHit rate > 90%
veltrixdb_storage_write_admission_throttles_total0
veltrixdb_vlog_garbage_ratio< 0.30
veltrixdb_vlog_gc_emergency_runs_total0
veltrixdb_scrub_corruption_total / veltrixdb_vlog_gc_read_errors_total0 (any increase = suspect disk)
veltrixdb_storage_transform_metadata_damaged0 (non-zero = run veltrix-repair)
veltrixdb_vlog_blkdiscard_errors_total0 (raw VLog without CAP_SYS_RAWIO)

Other useful series (every name below is defined in metrics/prometheus.go):

MetricWhat it shows
veltrixdb_storage_writes_total / veltrixdb_storage_reads_total / veltrixdb_storage_deletes_totalPer-node operation counters (as scraped with the node label)
veltrixdb_storage_write_latency_seconds / veltrixdb_storage_read_latency_seconds / veltrixdb_storage_delete_latency_secondsLatency histograms — source for P50/P95/P99 via histogram_quantile
veltrixdb_storage_wal_flushes_totalWAL group-commit fdatasync rate — compare against writes/s for amortization ratio
veltrixdb_vlog_writes_totalVLog append rate
veltrixdb_cache_hit_rate / veltrixdb_cache_size_bytes / veltrixdb_cache_max_size_bytesLIRS cache hit rate and RAM used vs. capacity
veltrixdb_cache_evictions_total (labeled type=lirs|ttl|defrag)Eviction pressure by cause
veltrixdb_vlog_file_bytesVLog size per NVMe disk — also the numerator for capacity planning against PVC size
veltrixdb_vlog_gc_runs_total / veltrixdb_vlog_gc_bytes_totalBackground GC activity
veltrixdb_storage_index_size_keysIn-memory index size (keys held in DRAM)
veltrixdb_storage_native_index_bytes New in v1.6Bytes held off the Go heap by the native C++ index (0 when the Go map index is in use). It is C memory outside the Go heap, so it is not in go_memstats_* (which v1.16 and earlier do not export at all); compare it with the container's RSS when sizing memory
veltrixdb_vlog_disk_slow / veltrixdb_vlog_disk_read_latency_ewma_secondsPer-disk slow-disk flag and smoothed read latency
veltrixdb_scrub_corruption_totalCRC32C mismatches found by the background scrubber — should stay 0
veltrixdb_cluster_nodes_totalCluster topology size, for multi-node deployments
veltrixdb_failure_detector_nodes_failed_total / _nodes_recovered_totalFailed minus recovered over a window = peers still down (there is no "currently failed" gauge)
veltrixdb_server_active_connections, veltrixdb_server_network_bytes_in_total / _out_totalClient connections and traffic
veltrixdb_storage_atomic_ops_totalSuccessful CAS/INCR/DECR/SETNX
veltrixdb_replication_lag_bytes, veltrixdb_replication_failures_totalReplicated mode only (absent in standalone and raft)
Exported but always 0 on v1.13 and earlier. veltrixdb_replication_lag_nanoseconds (nothing writes it; use lag_bytes or /admin/cluster), veltrixdb_cluster_partition_migrations_total (nothing increments it; use the [transfer] migration done moved=N log line) and veltrixdb_replication_conflict_resolutions_total / _vector_clock_updates_total (no conflict resolution runs). Fixed in v1.14 lag_nanoseconds is the age of the oldest write a replica has not acked (0 when caught up), partition_migrations_total counts key batches (≤ 500 keys) a new owner acknowledged, the two conflict / vector-clock counters are removed, and new series appear: veltrixdb_replication_replicas_failed / _replicas_sync_pending (gauges), _recovery_probes_total, _replica_recoveries_total and veltrixdb_failure_detector_nodes_reactivated_total (RECOVERING → ACTIVE). veltrixdb_cache_misses_total also counts lookups of keys that do not exist.

Useful PromQL for day-to-day operation:

rate(veltrixdb_storage_writes_total[1m])                            # write throughput
rate(veltrixdb_storage_reads_total[1m])                             # read throughput

rate(veltrixdb_cache_hits_total[5m]) /
  (rate(veltrixdb_cache_hits_total[5m]) + rate(veltrixdb_cache_misses_total[5m])) # hit ratio

rate(veltrixdb_storage_writes_total[1m]) / rate(veltrixdb_storage_wal_flushes_total[1m])  # WAL amortization

histogram_quantile(0.99, rate(veltrixdb_storage_read_latency_seconds_bucket[5m])) # P99 read

Search metrics New on main after v1.16 — ships in the next release

Every mode. The coordinating node counts each client vector (VSEARCH, VSEARCHX), text (TSEARCH) and hybrid (HSEARCH) request once, fan-out included; peer-to-peer /internal/search calls are not counted. Recording a request allocates nothing.

MetricMeaning
veltrixdb_search_requests_total{kind}Requests per kind = vector | text | hybrid, failed ones included
veltrixdb_search_errors_total{kind,reason}rebuilding (refused during the index rebuild), incomplete (a peer did not answer the fan-out), other
veltrixdb_search_latency_seconds{kind}Latency on the coordinating node, fan-out included (0.5 ms – 5 s buckets)
veltrixdb_search_partial_totalSearches answered without every peer (--search-allow-partial)
veltrixdb_search_ready1 when the search indexes are complete; 0 while the startup or snapshot-restore rebuild runs
veltrixdb_search_rebuild_loaded_keys / _rebuild_total_keysRebuild progress (the total stays 0 until the rebuild's scan finishes)
veltrixdb_search_vectors / _vector_tombstones / _vector_namespaces, veltrixdb_search_namespace_vectors{namespace}Live vectors, graph tombstones awaiting compaction, namespaces; per-namespace series for the first 64 namespaces only
veltrixdb_search_text_documents / _text_namespacesIndexed text documents and BM25 namespaces

Raft and snapshot metrics New on main after v1.16 — ships in the next release

--mode=raft only, read from the raft node at scrape time. On v1.16 and earlier read the term and leader from GET /admin/cluster or veltrix nodes.

MetricMeaning
veltrixdb_raft_term / _is_leaderCurrent term; 1 on the leader
veltrixdb_raft_commit_index / _applied_indexCommit and apply position; the difference is how stale local reads are
veltrixdb_raft_snapshot_index / _snapshot_term, _log_retained_entries, _snapshot_threshold_entriesSnapshot position, log kept after it, and --raft-snapshot-threshold
veltrixdb_raft_snapshot_captures_total / _installs_total, _chunks_sent_total / _chunks_received_total, _legacy_sent_totalCaptures, installs from a leader, InstallSnapshot chunks, single-shot snapshots sent to v1.16 and older followers
veltrixdb_raft_snapshot_last_capture_seconds / _last_apply_fence_seconds / _last_bytesDuration, Apply stall and file size of the last capture
veltrixdb_raft_snapshot_capture_failures_total, _sent_total, _transfer_failures_total, _install_failures_total, _restore_failures_totalFailed captures; leader: completed and failed transfers (including a single-shot over 256 MB, NOT sending snapshot … upgrade peer); follower: failed installs and restore attempts

Replication recovery metrics New on main after v1.16 — ships in the next release

--mode=replicated only. Per replica, the same state is in GET /admin/cluster as replication[].resync_pending and replication[].delete_gap. See Replication & CDC.

MetricMeaning
veltrixdb_replication_full_resyncs_totalCatch-ups that streamed the whole change feed (watermark older than the tombstone retention, or replication_state.json unreadable; ERROR FULL RESYNC)
veltrixdb_replication_catchup_gaps_totalRecoveries that could not replay everything the replica missed; deletes may be missing on it
veltrixdb_replication_replicas_delete_gap / _replicas_resync_pendingGauges: replicas flagged with a delete gap; replicas whose catch-up is pending or running
veltrixdb_replication_state_persists_total / _state_persist_errors_totalWrites of replication_state.json (at most one per second), and failed ones

Disk-failure auto-degrade

VeltrixDB detects failing disks automatically with a per-disk consecutive-error breaker: 5 consecutive I/O errors on a disk's WAL/VLog trip the breaker and mark the disk FAILED. Any successful I/O before the fifth error resets the streak, so transient hiccups don't trip it. Once tripped:

The breaker does not auto-reset. A failed disk is never automatically un-failed, even if subsequent I/O would succeed — recovery requires draining the node, replacing the disk, and restarting. See the Disaster Recovery runbook for the exact sequence.

Admin API

The same admin port also exposes a small JSON control-plane API, documented in full in the Admin API reference:

curl    http://localhost:2112/admin/stats       # engine snapshot (JSON)
curl    http://localhost:2112/admin/version     # schema version
curl -X POST http://localhost:2112/admin/checkpoint  # force WAL checkpoint
curl    http://localhost:2112/admin/cdc?prefix= # live CDC events (NDJSON)
curl    http://localhost:2112/admin/cluster     # topology: role, raft term/leader, peers, epoch, replica lag
curl    http://localhost:2112/admin/cluster/members  # membership (new on main after v1.16)

Grafana dashboards

The repository ships provisioned Grafana dashboards under grafana/ — a Prometheus datasource and dashboard provider under grafana/provisioning/, an operational dashboard (veltrixdb_dashboard.json: throughput, latency percentiles, cache hit rate and evictions, per-disk VLog size and garbage ratio, GC), a larger veltrixdb_complete_dashboard.json, and a CI dashboard (ci_dashboard.json). The runtime, process, system and disk panels query veltrixdb_runtime_* / veltrixdb_process_* / veltrixdb_system_* / veltrixdb_disk_* series from the hardware collector, which v1.16 and earlier do not register, so they stay empty against those servers (New on main after v1.16 — ships in the next release registered).

The repository also ships monitoring/servicemonitor.yaml (scrapes port metrics every 15 s on pods labelled app.kubernetes.io/name=veltrixdb in namespace veltrixdb) and monitoring/prometheus-rules.yaml, a PrometheusRule with 10 alerts in v1.16:

AlertFires on
VeltrixDBWriteThrottleActiverate(write_admission_throttles_total[2m]) > 10 for 2 m
VeltrixDBVLogGCStalledGC skipped as paused while garbage_ratio > 0.5, 5 m
VeltrixDBVLogReadErrorsany vlog_gc_read_errors_total increase (critical)
VeltrixDBScrubCorruptionany scrub_corruption_total increase in 15 m (critical)
VeltrixDBLowCacheHitRatehit rate < 50% for 10 m
VeltrixDBHighReadLatencyread P99 > 10 ms for 5 m
VeltrixDBNodeFailedfailed minus recovered peers > 0 over 10 m (critical)
VeltrixDBClusterShrankcluster_nodes_total below its 1-hour max
VeltrixDBDiskUsageHigh/mnt/nvme* > 85% full — needs node-exporter
VeltrixDBProcessRestartedprocess_start_time_seconds{job="veltrixdb"} — never fires against a v1.16 or earlier server, which exports no process_* metrics; supply a process exporter or drop it

New on main after v1.16 — ships in the next release the rules file has 24 rules (the Helm chart's prometheusRule.extendedAlerts groups match), and a test starts a raft and a replicated server and fails if a rule names a metric neither serves:

Profiling New in v1.7

Start the server with -pprof-addr=127.0.0.1:6060 to serve CPU, heap, goroutine and execution-trace profiles on a separate listener (never the metrics port):

go tool pprof http://127.0.0.1:6060/debug/pprof/profile?seconds=30   # CPU
go tool pprof http://127.0.0.1:6060/debug/pprof/heap                 # heap
curl -o trace.out 'http://127.0.0.1:6060/debug/pprof/trace?seconds=5' # execution trace

New in v1.16 /debug/pprof/mutex and /debug/pprof/block stay empty unless you also pass -pprof-mutex-fraction N (sample 1 in N mutex contention events; 5–100 is typical) and -pprof-block-rate NS (record blocking events of at least NS nanoseconds, e.g. 10000). Both default to 0 (off) and are ignored without -pprof-addr.

When the experimental C++ network front-end (-net=cpp|uring|poll) is in use, the server also logs a per-stage latency report at shutdown (stages iter, cb_enter, exec, put_sched, put_exec, wake, defer_sched, defer_exec; log2 µs buckets).