Metrics reference

The full catalogue of Prometheus meters StoatFlow exposes on /metrics — name, type, tags, and what each one measures, grouped by area.

The :runtime module exports metrics on GET /metrics in Prometheus text format, backed by a Micrometer PrometheusMeterRegistry. This page is the meter catalogue: every StoatFlow meter the current release registers, grouped by area, with its type, tags, and a one-line description. For how to enable, scrape, and configure metrics — recording levels, naming rewrites, PromQL examples — see Metrics. For what to alert on, see Observability.

Contract. This catalogue lists the stable meter set. The live /metrics scrape is authoritative for the exact tag sets and any point-release additions — when in doubt, trust the scrape.

How to read this page

  • Meter — the canonical dotted metric ID. Prometheus rewrites . to _ and appends the type suffix (_total for counters; _seconds_count / _seconds_sum / _seconds_max for timers), so stoatflow.barrier.commit.latency is scraped as stoatflow_barrier_commit_latency_seconds_*.
  • Tags — per-meter tags beyond the common ones. Every StoatFlow meter carries application_id; the registry-level application tag plus anything under runtime.metrics.common-tags is applied to every meter on the endpoint, including JVM and Kafka-client meters.
  • Recording level — meters marked (debug) in the description only appear with runtime.metrics.recording-level: debug; everything else is exported at the default info level.
  • The commit-path latency timers publish client-side P50/P95/P99 quantiles as {quantile="…"} series on the base _seconds name — there are no _bucket histograms.

Application and engine

MeterTypeTagsWhat it measures
stoatflow.client.stateGaugeApplication state ordinal: CREATED=0, STARTING=1, VALIDATING_STATE=2, RESTORING=3, RUNNING=4, DRAINING=5, PAUSED=6, STOPPING=7, STOPPED=8, ERROR=9.
stoatflow.client.lane.aliveGaugeCurrently alive/healthy lanes.
stoatflow.client.uptime.secondsGaugeSeconds since the application started.
stoatflow.client.start.time.epoch.secondsGaugeApplication start time (epoch seconds).
stoatflow.lanesGaugesub_topology, chainConfigured key-affinity lanes per sub-topology; sum(stoatflow_lanes) gives the cross-topology total.
stoatflow.engine.restart.totalCounterdisposition, target, triggerSuccessful in-place engine restarts (fault recovery, programmatic, HA demote).
stoatflow.topology.statelessGauge1 if the topology has no state stores, 0 otherwise.
stoatflow.topology.event.time.trackingGauge1 if watermark tracking is active, 0 if bypassed.
stoatflow.topology.dispatch.modeGauge0 for timestamp-ordered dispatch, 1 for FIFO.

Lanes and throughput

MeterTypeTagsWhat it measures
stoatflow.lane.queue.sizeGaugelane_id, chainCurrent lane queue depth (backpressure signal).
stoatflow.lane.queue.capacityGaugesub_topology, chainConfigured lane queue capacity per sub-topology.
stoatflow.lane.queue.full.totalCounterlane_idTimes a lane queue was full (backpressure events).
stoatflow.lane.records.processed.totalCounterlane_idRecords processed by a lane.
stoatflow.lane.bytes.processed.totalCounterlane_idBytes processed by a lane.
stoatflow.lane.process.latencyTimerlane_idPer-record processing latency.
stoatflow.e2e.latencyTimerPer-record end-to-end latency, record timestamp to processing completion (KS record-e2e-latency analogue).

Lane IDs follow the {subtopology}_{lane} convention — e.g. 0_0, 1_7. Aggregate with a regex matcher: sum(stoatflow_lane_queue_size{lane_id=~"1_.*"}).

Commit barriers and transactions

MeterTypeTagsWhat it measures
stoatflow.barrier.initiated.totalCounterBarriers initiated.
stoatflow.barrier.completed.totalCounterBarriers successfully completed.
stoatflow.barrier.failed.totalCountererror_typeBarrier failures, by error type.
stoatflow.barrier.in.flightGaugeCurrently pending barriers.
stoatflow.barrier.latencyTimerBarrier initiation to completion.
stoatflow.barrier.alignment.latencyTimerTime for all lanes to receive the barrier.
stoatflow.lane.holdback.recordsDistributionSummarysub_topologyRecords held back and replayed per barrier at a sub-topology boundary — receiver-side epoch hold-back that keeps the commit a consistent cut across the cascade (ADR-135).
stoatflow.lane.holdback.drains.totalCountersub_topologyNon-empty hold-back drains — a receiving lane replayed stashed ahead-of-epoch records after crossing its barrier (ADR-135).
stoatflow.barrier.commit.latencyTimerCommit latency: producer drain + Kafka TX + state flush (KS commit-latency analogue).
stoatflow.barrier.records.committed.totalCounterRecords committed across barriers.
stoatflow.barrier.bytes.committed.totalCounterBytes committed across barriers.
stoatflow.barrier.subtopology.received.totalCountersubtopology_idBarriers received per sub-topology. (debug)
stoatflow.barrier.subtopology.pending.lanesGaugesubtopology_idPending lane completions per sub-topology. (debug)
stoatflow.barrier.interval.target.msGaugeCurrent target barrier-to-barrier interval (ms).
stoatflow.barrier.commit.duration.estimate.msGaugeSmoothed estimate of commit duration (ms).
stoatflow.barrier.epoch.max.recordsGaugeCurrent dynamic epoch record limit.
stoatflow.barrier.epoch.actual.recordsGaugeRecords dispatched in the last epoch.
stoatflow.barrier.epoch.memory.capGaugeMemory-derived epoch record cap; -1 = uncapped.
stoatflow.barrier.epoch.bytes.per.recordGaugeSmoothed uncommitted state bytes per record (feeds the memory cap).
stoatflow.s1.epoch.records.smoothedGaugeSmoothed epoch-records average used by the epoch-size controller.
stoatflow.s1.cap.grow.events.totalCounterreasonEpoch-cap grow events by binding signal (record_count, memory_pressure, stall, soft_binding, time_grow).
stoatflow.s1.cap.decay.events.totalCounterEpoch-cap decay events.
stoatflow.barrier.trigger.totalCountertriggerBarrier creation count by trigger: TIME, RECORD_COUNT, MEMORY_PRESSURE, CACHE_PRESSURE.
stoatflow.dispatcher.stall.latencyTimerDispatcher stall time waiting for an active commit after hitting the epoch record limit.
stoatflow.barrier.commit.changelog.latencyTimerAggregate changelog serialization+send latency per commit epoch.
stoatflow.barrier.commit.state.flush.latencyTimerAggregate state-store flush latency per commit epoch.
stoatflow.barrier.commit.producer.flush.latencyTimerPre-commit producer flush latency.
stoatflow.barrier.commit.send.offsets.latencyTimersendOffsetsToTransaction RPC latency.
stoatflow.barrier.commit.queue.wait.latencyTimerBarrier wait in the commit queue between alignment and commit-thread pickup.
stoatflow.barrier.commit.post.tx.latencyTimerPost-transaction phase latency (guard wait + epoch prepare + send-buffer drain).
stoatflow.barrier.commit.window.durationTimerDuration of the commit-in-progress blocking window. (debug)
stoatflow.commit.state.flush.guard.waitTimerTime the next transaction waited on the previous epoch's async state flush.
stoatflow.commit.state.flush.async.latencyTimerAsync (off-commit-path) state flush latency.
stoatflow.commit.state.flush.overlapCounterCommits that overlapped a still-running previous flush.
stoatflow.commit.stall.detected.totalCounterCommit-pipeline stalls detected by the in-process watchdog.
stoatflow.commit.stall.duration.msGaugeAge of the most recently observed commit stall (ms).
stoatflow.transaction.begin.totalCounterKafka transactions begun.
stoatflow.transaction.commit.totalCounterKafka transactions committed.
stoatflow.transaction.abort.totalCounterKafka transactions aborted.
stoatflow.transaction.commit.latencyTimerKafka transaction commit latency.
stoatflow.alo.commit.delegation.waitTimerCommit delegation wait (at-least-once mode only).
stoatflow.alo.commit.sync.latencyTimercommitSync latency (at-least-once mode only).
stoatflow.commit.barrier.idle.throttledGauge1 while the barrier scheduler is parked on the stretched warm-idle cadence, else 0 (ADR-134).

State stores and caching

Most store meters are per-store (store_name) and require recording-level: debug; the changelog counters and store.num.keys are exported at info.

MeterTypeTagsWhat it measures
stoatflow.store.get.totalCounterstore_nameGet operations. (debug)
stoatflow.store.put.totalCounterstore_namePut operations. (debug)
stoatflow.store.delete.totalCounterstore_nameDelete operations. (debug)
stoatflow.store.get.latencyTimerstore_namePoint-read latency. (debug)
stoatflow.store.put.latencyTimerstore_nameWrite latency. (debug)
stoatflow.store.delete.latencyTimerstore_nameDelete latency. (debug)
stoatflow.store.range.latencyTimerstore_nameRange query latency. (debug)
stoatflow.store.all.latencyTimerstore_nameFull-iteration latency. (debug)
stoatflow.store.flush.latencyTimerstore_nameStore flush latency. (debug)
stoatflow.store.cache.hit.totalCounterstore_nameStore cache hits. (debug)
stoatflow.store.cache.miss.totalCounterstore_nameStore cache misses. (debug)
stoatflow.store.changelog.records.written.totalCounterstore_nameChangelog records written.
stoatflow.store.changelog.bytes.written.totalCounterstore_nameChangelog bytes written.
stoatflow.store.commit.changelog.latencyTimerstore_namePer-store changelog serialization+send latency during the commit epoch. (debug)
stoatflow.store.commit.flush.latencyTimerstore_namePer-store flush latency during the commit epoch. (debug)
stoatflow.store.flush.entriesDistributionSummarystore_nameEntry count per epoch flush. (debug)
stoatflow.store.flush.sub.batchesDistributionSummarystore_nameSub-batch count per flush (1 = sequential, N = parallel). (debug)
stoatflow.store.num.keysGaugestore_name, store_typeCommitted key count of an in-memory store (KIP-1250 parity); silent for RocksDB-backed stores.
stoatflow.store.expired.recordsCounterstore_name, store_typeRecords event-time-expired (pruned past retention) from an in-memory window or session store; 0 for plain key-value stores (ADR-133).
stoatflow.store.format.downgrade.totalCounteroutcomeState stores whose on-disk format was newer than the topology asked for — record headers (KIP-1271) turned off over a store that carries them. Reported once per affected store at startup, before it opens. outcome is dropped-empty (the headers keyspace was empty and was dropped in place — free, no restore), wiped (acknowledged via stoatflow.state.format-downgrade: wipe-and-restore in YAML, or the state.format.downgrade Properties key; local state deleted and rebuilt from the changelog) or refused (startup failed). Do not alert on refused: the process exits moments later, so a scrape almost never lands in the window — treat a refusal as a log/crash-loop signal, and use this counter for the dropped-empty and wiped outcomes, which run on a process that goes on to serve. See state stores.
stoatflow.fk.enumeration.behind.scansCounterstore_nameForeign-key join evaluations that enumerated the subscription store as-of an earlier committed epoch because the reader was behind (ADR-136).
stoatflow.suppress.buffer.countGaugebuffer_nameRecords currently held in a suppression buffer.
stoatflow.suppress.buffer.bytesGaugebuffer_nameBytes currently held in a suppression buffer.
stoatflow.suppress.emit.totalCounterbuffer_nameRecords released from a suppression buffer.

Suppression buffers never drop records, so there is no drop counter here: a late record is dropped upstream by the windowed-aggregation guards and counted as stoatflow.dropped.records.total with reason=late_window or late_session. On a full buffer, EAGER early-emits the oldest entry (a forward, not a drop) while STRICT and maxBytes throw.

RocksDB

Opt-in, and off by default — set stoatflow.rocks-db.metrics.enabled: true for the property and cache gauges (info, cheap), and additionally statistics-enabled: true for the ticker, ratio and histogram meters (debug; enabling RocksDB statistics costs roughly 5–10% on the write path, and takes effect at store open, so it needs a restart). A recorder thread samples every interval-ms (default 60 s).

This section elides related meters into one row — compaction.time.{avg,min,max}.ms is three meters, not one. That is a deliberate exception to the rest of this page, which spells every name out: the family is ~43 series per store, and elision keeps it readable. All meters carry store_name except the three global shared-cache gauges.

Two caveats worth knowing before you build a dashboard on these. open.files is not published — it is derived from a RocksDB ticker (NO_FILE_CLOSES) that no longer exists in the bundled RocksJava. And *.min.ms is JNI-only: the default FFM backend reads statistics from a text dump that carries no MIN token, so those gauges stay silent unless you set stoatflow.rocks-db.backend: JNI. Averages, maxima and totals are unaffected.

MeterTypeTagsWhat it measures
stoatflow.rocksdb.{bytes.written,bytes.read}.totalCounterstore_nameBytes written / read by RocksDB. (debug)
stoatflow.rocksdb.memtable.bytes.flushed.totalCounterstore_nameBytes written to disk by memtable flushes. (debug)
stoatflow.rocksdb.compaction.bytes.{read,written}.totalCounterstore_nameBytes read / written by compaction — the write-amplification signal. (debug)
stoatflow.rocksdb.file.errors.totalCounterstore_nameRocksDB file errors. (debug)
stoatflow.rocksdb.memtable.hit.ratioGaugestore_nameMemtable hit ratio over the last sample interval. (debug)
stoatflow.rocksdb.block.cache.{,data.,index.,filter.}hit.ratioGaugestore_nameBlock-cache hit ratio over the last sample interval — overall, then per block role. A falling data-block ratio with a healthy index ratio usually means the working set outgrew the cache. (debug)
stoatflow.rocksdb.compaction.time.{avg,min,max}.msGaugestore_nameCompaction time. (debug)
stoatflow.rocksdb.compaction.time.total.msCounterstore_nameCumulative compaction time. (debug)
stoatflow.rocksdb.flush.time.{avg,min,max}.msGaugestore_nameMemtable-flush time. (debug)
stoatflow.rocksdb.flush.time.total.msCounterstore_nameCumulative memtable-flush time. (debug)
stoatflow.rocksdb.write.stall.duration.avg.msGaugestore_nameWrite-stall duration. Any sustained value is RocksDB backpressuring your commit path. (debug)
stoatflow.rocksdb.write.stall.duration.total.msCounterstore_nameCumulative time writes were stalled. (debug)
stoatflow.rocksdb.num.immutable.mem.tableGaugestore_nameImmutable memtables not yet flushed.
stoatflow.rocksdb.{cur.size.active.mem.table,cur.size.all.mem.tables,size.all.mem.tables}.bytesGaugestore_nameMemtable sizes: active, active plus unflushed, and including pinned.
stoatflow.rocksdb.num.entries.{active.mem.table,imm.mem.tables}Gaugestore_nameEntries in the active / unflushed immutable memtables.
stoatflow.rocksdb.num.deletes.{active.mem.table,imm.mem.tables}Gaugestore_nameDelete entries in the active / unflushed immutable memtables.
stoatflow.rocksdb.{mem.table.flush.pending,compaction.pending}Gaugestore_name1 while a flush / compaction is pending, else 0.
stoatflow.rocksdb.num.running.{flushes,compactions}Gaugestore_nameCurrently running flushes / compactions.
stoatflow.rocksdb.estimate.pending.compaction.bytesGaugestore_nameBytes compaction must rewrite to bring the LSM tree back to target size. A climbing value means compaction is losing ground.
stoatflow.rocksdb.{total.sst.files.size,live.sst.files.size}.bytesGaugestore_nameSST bytes on disk: all files, and those in the latest version.
stoatflow.rocksdb.num.live.versionsGaugestore_nameLive versions — more than one means an open iterator is pinning old files.
stoatflow.rocksdb.estimate.num.keysGaugestore_nameEstimated live keys. This is the RocksDB counterpart of store.num.keys, which covers in-memory stores only.
stoatflow.rocksdb.estimate.table.readers.mem.bytesGaugestore_nameMemory held by table readers (indexes and filters), outside the block cache.
stoatflow.rocksdb.background.errorsGaugestore_nameAccumulated background errors. Alert on any non-zero value.
stoatflow.rocksdb.block.cache.{capacity,usage,pinned.usage}.bytesGaugestore_nameThe shared block cache, repeated per store so Kafka Streams dashboards port unchanged.
stoatflow.rocksdb.shared.block.cache.{capacity,usage,pinned.usage}.bytesGaugeThe shared block cache, reported once. StoatFlow runs one LRU cache across all stores, so these are the real numbers — prefer them over the per-store duplicates above.

State restoration

MeterTypeTagsWhat it measures
stoatflow.restoration.in.progressGauge1 while restoration is running, 0 otherwise.
stoatflow.restoration.stores.totalGaugeTotal stores to restore.
stoatflow.restoration.stores.completedGaugeStores that have finished restoring.
stoatflow.restoration.records.restored.totalCounterstore_nameRecords restored, per store.
stoatflow.restoration.bytes.restored.totalCounterstore_nameChangelog bytes restored, per store — serialized key plus value as read off the changelog, excluding record and batch overhead. Compare against changelog volume to size a cold start.
stoatflow.restoration.duration.secondsTimerstore_namePer-store restoration duration, recorded once when the store finishes. A store's changelog partitions restore in parallel, so this is the slowest partition, not their sum.

Consumer, producer, and buffers

MeterTypeTagsWhat it measures
stoatflow.consumer.poll.latencyTimerConsumer poll latency.
stoatflow.consumer.poll.totalCounterPoll invocations.
stoatflow.consumer.poll.recordsDistributionSummaryRecords per poll.
stoatflow.consumer.records.consumed.totalCountertopic, partitionRecords consumed.
stoatflow.consumer.bytes.consumed.totalCountertopic, partitionBytes consumed.
stoatflow.consumer.lag.recordsGaugetopic, partitionConsumer lag, in records.
stoatflow.consumer.assigned.partitionsGaugeNumber of assigned partitions.
stoatflow.consumer.partitions.pausedGaugeCurrently paused partitions.
stoatflow.consumer.partitions.delay.pendingGaugePartitions with a pending resume delay.
stoatflow.consumer.partition.paused.totalCountertopic, partition, reasonPartition pause events, by reason.
stoatflow.consumer.partition.resumed.totalCountertopic, partition, reasonPartition resume events, by reason.
stoatflow.producer.records.produced.totalCountertopicRecords produced.
stoatflow.producer.bytes.produced.totalCountertopicBytes produced.
stoatflow.producer.send.latencyTimertopicProducer send latency. (debug)
stoatflow.buffer.partition.sizeGaugetopic, partitionCurrent partition buffer depth. (debug)
stoatflow.buffer.partition.capacityGaugetopic, partitionPartition buffer capacity. (debug)
stoatflow.buffer.offer.totalGaugetopic, partitionCumulative records offered to the partition buffer. (debug)
stoatflow.buffer.poll.totalGaugetopic, partitionCumulative records polled from the partition buffer. (debug)
stoatflow.buffer.oldest.age.msGaugetopic, partitionAge of the oldest buffered record. (debug)
stoatflow.buffer.scheduled.source.sizeGaugeScheduled-source dispatch buffer depth.
stoatflow.buffer.timer.event.sizeGaugeEvent-time timer buffer depth.
stoatflow.buffer.timer.processing.sizeGaugeProcessing-time timer buffer depth.

Dispatcher internals

MeterTypeTagsWhat it measures
stoatflow.dispatcher.batch.sizeDistributionSummaryRecords per dispatch batch. (debug)
stoatflow.dispatcher.batch.held.totalCounterBatches held because a target lane lacked capacity. (debug)
stoatflow.dispatcher.dispatch.latencyTimerPer-batch dispatch latency.
stoatflow.parallel.deser.activated.totalCounterTimes parallel deserialization was activated.
stoatflow.queue.offer.failure.totalCounterqueue_typeInternal queue offer rejections (lane, partition_buffer, commit).
stoatflow.coordinator.select.latencyTimerTime spent selecting the next timestamp-ordered batch. (debug)
stoatflow.coordinator.partition.switchesDistributionSummaryPartition switches per selected batch. (debug)

Watermarks and event time

MeterTypeTagsWhat it measures
stoatflow.watermark.currentGaugeCurrent global watermark (epoch ms).
stoatflow.watermark.lag.msGaugeWall-clock time minus watermark (event-time lag).
stoatflow.watermark.advance.totalCounterWatermark advancement events.
stoatflow.watermark.partition.currentGaugetopic, partitionPer-partition watermark. (debug)
stoatflow.watermark.late.records.totalCountertopic, partitionRecords arriving after the watermark. (debug)
stoatflow.watermark.out.of.orderness.maxGaugeMaximum observed out-of-orderness (ms). (debug)
stoatflow.watermark.alignment.drift.msGaugetopic, partition, groupPer-partition drift above the alignment group's minimum watermark. (debug)
stoatflow.watermark.alignment.group.minGaugegroupMinimum watermark across the alignment group (epoch ms). (debug)
stoatflow.watermark.alignment.partitions.pausedGaugegroupPartitions currently paused for watermark alignment.

Timers, punctuators, and scheduled sources

MeterTypeTagsWhat it measures
stoatflow.timer.registered.totalCountertypeKeyed timers registered (event_time, processing_time).
stoatflow.timer.fired.totalCountertypeTimers fired.
stoatflow.timer.deleted.totalCountertypeTimers explicitly deleted.
stoatflow.timer.queue.sizeGaugetypeTimer dispatch-buffer depth, by timer type.
stoatflow.timer.fire.latencyTimertypeDelay between scheduled and actual fire time. (debug)
stoatflow.timer.fire.late.totalCountertypeTimers that fired late. (debug)
stoatflow.punctuator.invocation.totalCounterpunctuator_id, type, modePunctuator invocations.
stoatflow.punctuator.skip.totalCounterpunctuator_idPunctuator invocations skipped (previous run still active).
stoatflow.punctuator.activeGaugeCurrently registered punctuators.
stoatflow.punctuator.execution.latencyTimerpunctuator_id, typePunctuator execution time. (debug)
stoatflow.scheduled.source.trigger.totalCountersource_name, typeScheduled source triggers.
stoatflow.scheduled.source.records.emitted.totalCountersource_nameRecords emitted by scheduled sources.

Error handling

MeterTypeTagsWhat it measures
stoatflow.error.totalCountererror_type, topicErrors by type (topic omitted when unknown).
stoatflow.error.typed.totalCountercategory, error_typeCategorised errors (e.g. production failures), by category and type.
stoatflow.dropped.records.totalCounterreasonRecords dropped before processing (KS dropped-records parity). The reason tag is the semantics — six values: null_key (a record whose key is null, or serializes to null, reaching an aggregation), late_window / late_session (a record arriving after its window or session already closed), join_null_key / join_null_value (a join input the join cannot match on), table_source_null_key (a null-keyed record on a KTable source topic).
stoatflow.sink.records.dropped.totalCountersink_name, topicRecords dropped because a custom partitioner returned no partition (KIP-837).
stoatflow.sink.records.multicast.totalCountersink_name, topicOutput records produced via multicast — a custom partitioner returned multiple partitions (KIP-837).
stoatflow.dlq.poison.quarantined.totalCounterSource records quarantined as poison after an asynchronous broker-side production failure returned continue. The epoch's source offsets are held and the epoch is replayed with exactly these records skipped, so the epoch's other records survive — but a quarantined record loses all of its outputs, across every sink it fans out to. See Error-handling model.
stoatflow.dlq.poison.replays.totalCounterPoison-epoch replays: in-place engine restarts that reprocess an aborted epoch with the quarantined records skipped. Bounded by stoatflow.commit-barrier.max-poison-replays within poison-replay-window-ms. That budget is in-memory — exhausting it ends the process and the pod restarts with a clean budget — so continue is bounded per process, never end to end. Alert on this meter.
stoatflow.dlq.poison.replay.budget.exhausted.totalCounterThe replay budget ran out: max-poison-replays replays were already consumed within poison-replay-window-ms, so the instance shut down with the source offsets held rather than replaying again. Terminal — any non-zero value is an incident. Alert on it alongside …replays.total, which counts replays and therefore stops incrementing at the moment a non-converging poison starts crash-looping the pod.
stoatflow.dlq.poison.quarantine.sizeGaugeSource offsets currently quarantined and skipped by a replay. 0 in steady state; entries retire as soon as a commit moves permanently past them.

High availability

Registered only when hot standby is enabled (ha.mode != off).

MeterTypeTagsWhat it measures
stoatflow.ha.roleGauge1 when this pod is the active, 0 when standby.
stoatflow.ha.standby.replication.lag.recordsGaugeTotal committed-changelog lag in records across all changelog partitions; 0 when active or caught up.
stoatflow.ha.standby.replication.applied.recordsCounterCumulative changelog records the standby applier has applied; rate(...) = apply throughput.
stoatflow.ha.standby.replication.lag.msGaugeStandby replication lag in milliseconds.
stoatflow.ha.peer.freshness.msGaugeTime since the freshest observed peer's last heartbeat.
stoatflow.ha.peersGaugeNumber of observed HA peers.
stoatflow.ha.restart.requiredGauge1 when this pod needs a restart (e.g. after a source-topic partition-count change).
stoatflow.ha.restartingGauge1 while this pod is restarting its engine in place to absorb a processing fault. The pod stays ACTIVE throughout, so stoatflow.ha.role does not move — this is what distinguishes "absorbing a fault" from "healthy".
stoatflow.ha.redundancy.ready.standbysGaugeCaught-up (READY_STANDBY) fresh standby count, including self.
stoatflow.ha.redundancy.below.desiredGauge1 when the active has fewer ready standby spares than ha.desired-standbys.
stoatflow.ha.token.epochGaugeCurrent promotion-token epoch on the metadata topic.
stoatflow.ha.election.outcomeCounteroutcomeCumulative election outcomes: won, reclaimed, stood_down_fresh, stood_down_lost.
stoatflow.ha.election.latency.msGaugeLast claim-to-ACTIVE promotion latency (ms); -1 until the first promotion.

License

Registered once at startup; exported at every recording level. See License configuration.

MeterTypeTagsWhat it measures
stoatflow.license.validGaugetier1 under a VALID or GRACE_PERIOD license, else 0.
stoatflow.license.expiry_timestamp_secondsGaugeUnix epoch seconds of the license entitlement deadline.
stoatflow.license.days_remainingGaugeWhole days until expiry; negative within the post-expiry grace window.
stoatflow.license.grace_remaining_secondsGaugeSeconds left in the offline-grace budget; floored at 0.
stoatflow.license.heartbeat_consecutive_failuresGaugeHeartbeat ticks failed since the last success.
stoatflow.license.heartbeat_last_success_timestamp_secondsGaugeUnix epoch seconds of the last successful heartbeat.
stoatflow.license.validations_totalCounterresultCold-start validation outcomes, by result.
stoatflow.license.heartbeats_totalCounterresultHeartbeat tick outcomes, by result.

JVM, system, and Kafka-client meters

Beyond the stoatflow.* meters above, the same endpoint carries:

  • JVM and system meters (jvm_*, system_*, process_*) — bound by default (runtime.metrics.bind-jvm-metrics: true): heap/non-heap memory, GC pauses, thread counts, classloading, CPU usage.
  • Native Kafka client meters (kafka_consumer_*, kafka_producer_*) — the Kafka clients' own JMX metrics surfaced through Micrometer.

These carry the registry common tags (application plus your common-tags) but not application_id. See Metrics for details.

Next steps

  • Metrics — enabling, scraping, recording levels, naming and tag conventions, PromQL examples.
  • Observability — wiring /metrics into a monitoring stack and what to alert on.
  • Configuration reference — the runtime.metrics.* keys.