Skip to content

Metrics Reference

PrkDB exports Prometheus metrics from the shared registry in crates/prkdb/src/prometheus_metrics.rs.

Where Metrics Are Exposed

  • prkdb-server: http://<host>:9090 + NODE_ID/metrics
  • prkdb-cli serve --prometheus: http://<host>:<port>/metrics

The HTTP server now re-exports the real Prometheus registry instead of placeholder counters.

Core Health Metrics

MetricTypeDescription
prkdb_upGaugeServer liveness by node_id
prkdb_collections_activeGaugeNumber of active collections
prkdb_collection_size_bytesGaugeCollection size by node_id and collection

Raft Metrics

MetricTypeDescription
prkdb_raft_stateGaugeCurrent Raft state by node_id and partition
prkdb_raft_termGaugeCurrent term
prkdb_raft_commit_indexGaugeCommit index
prkdb_raft_leader_elections_totalCounterTotal leader elections
prkdb_raft_heartbeats_sent_totalCounterHeartbeats sent to peers
prkdb_raft_heartbeats_failed_totalCounterFailed heartbeats
prkdb_raft_append_entries_totalCounterAppendEntries RPCs by result
prkdb_raft_snapshot_indexGaugeLast snapshot index

Snapshot Metrics

MetricTypeDescription
prkdb_snapshots_created_totalCounterSnapshots created
prkdb_snapshot_creation_duration_secondsHistogramSnapshot creation latency

Operation Metrics

MetricTypeDescription
prkdb_ops_totalCounterTotal operations
prkdb_reads_totalCounterTotal reads
prkdb_writes_totalCounterTotal writes
prkdb_deletes_totalCounterTotal deletes
prkdb_delete_batches_totalCounterDelete batch operations
prkdb_operation_duration_secondsHistogramOperation latency
prkdb_read_duration_secondsHistogramRead latency
prkdb_write_duration_secondsHistogramWrite latency
prkdb_batch_duration_secondsHistogramBatch write latency

Cache Metrics

MetricTypeDescription
prkdb_cache_hits_totalCounterCache hits
prkdb_cache_misses_totalCounterCache misses
prkdb_cache_hit_ratioGaugeCache hit ratio

Example Checks

/metrics requires an Admin bearer token:

bash
curl -H "Authorization: Bearer $PRKDB_BOOTSTRAP_TOKEN" http://127.0.0.1:9091/metrics | grep prkdb_up
curl -H "Authorization: Bearer $PRKDB_BOOTSTRAP_TOKEN" http://127.0.0.1:9091/metrics | grep prkdb_raft_state
curl -H "Authorization: Bearer $PRKDB_BOOTSTRAP_TOKEN" http://127.0.0.1:9091/metrics | grep prkdb_operation_duration_seconds

Alert Ideas

Node down

promql
prkdb_up == 0

Frequent leader elections

promql
rate(prkdb_raft_leader_elections_total[5m]) > 0

Heartbeat failures

promql
rate(prkdb_raft_heartbeats_failed_total[5m]) > 0

High write latency

promql
histogram_quantile(0.99, sum by (le) (rate(prkdb_write_duration_seconds_bucket[5m])))

Write path not confirming writes

promql
prkdb_writer_healthy == 0

The failure this catches: the WAL writer accepts writes into a queue and publishes them in the background. If it exits or stops making progress, the process stays up and answers HTTP normally while every client write hangs unconfirmed. Latency histograms do not catch it, because a write that never completes never records a duration — the p99 stays flat while nothing is being written at all. prkdb_up stays at 1 for the whole outage.

MetricTypeDescription
prkdb_writer_healthyGauge1 while the write path confirms writes, 0 once it has exited or stalled
prkdb_write_queue_depthGaugeWrites queued and not yet published
prkdb_write_queue_oldest_age_msGaugeAge of the oldest unpublished write
prkdb_writer_last_publish_age_msGaugeMilliseconds since the last publish; -1 if it never has
prkdb_writer_publishes_totalCounterBatches published since start

Read them together:

patternmeaning
queue_depth rising, oldest_age_ms risingwriter falling behind — a capacity problem
queue_depth non-zero, last_publish_age_ms growingwriter has stopped publishing — trips healthy to 0
queue_depth 0, last_publish_age_ms growingidle, not stalled. Normal.

The third row is why the check requires a non-empty queue: a database nobody is writing to also has an old last-publish time, and flagging that would make the alert useless.

-1 for "never published" rather than 0, because 0 reads as "published just now" — the opposite of the truth, and the reassuring direction to be wrong in.

Publish throughput is derived by the scraper rather than exported pre-computed:

promql
rate(prkdb_writer_publishes_total[5m])

A rate computed inside the process and exported as a gauge cannot handle windowing or survive a restart, which is why the in-process one was removed rather than kept.

The same facts are on /health under write_path, for orchestrators that probe rather than scrape.