Prometheus metrics

bee-tui can expose a Prometheus /metrics endpoint with the gauges the cockpit screens already compute. The point isn't to duplicate Bee's own /metrics — Bee exposes plenty of infrastructure counters — it's to make bee-tui's unique synthesised gauges machine-readable so a Grafana board can graph them alongside Bee's:

  • Per-batch worst-bucket fill — predicts upload-failure before Bee's API admits anything is wrong.
  • Predictive stamp economics — depth, capacity bytes, TTL seconds per batch (same math as :*-preview).
  • Pending-tx age — operator-relevant signal that Bee surfaces only as a creation timestamp.
  • Depth-vs-radius gapcommitted_depth - storage_radius; positive means the node hosts chunks beyond its storage radius (chunk-loss risk during shrinkage).
  • bee-tui's own request stats — p50/p99/error-rate over the recent client-side log-capture window. Distinguishes "Bee is slow" from "the network between bee-tui and Bee is slow".

Enable it

In config.toml:

[metrics]
enabled = true
addr    = "127.0.0.1:9101"   # default; only opt into 0.0.0.0 if you mean it

Off by default — exposing an HTTP listener should be a deliberate operator opt-in, even on localhost.

Scrape config

Standard Prometheus drop-in:

scrape_configs:
  - job_name: bee-tui
    static_configs:
      - targets: ['127.0.0.1:9101']
    scrape_interval: 30s

bee-tui re-renders the metrics on every scrape, reading the latest snapshots from the same watch channels the screens use — so the values match what the operator sees in the cockpit at the moment of the scrape.

Metric reference

All metrics are namespaced bee_tui_. Gauges unless noted.

Liveness + identity

MetricLabelsDescription
bee_tui_upAlways 1 if the scrape responds
bee_tui_infoversion, overlay, bee_modeAlways 1; metadata via labels
bee_tui_resource_loadedresource1 if that resource's last poll succeeded (health / stamps / swap / lottery / topology / network / transactions)

Status (/status)

MetricDescription
bee_tui_status_connected_peersStatus.connectedPeers
bee_tui_status_neighborhood_sizeStatus.neighborhoodSize
bee_tui_status_reserve_size_chunksStatus.reserveSize
bee_tui_status_reserve_size_within_radius_chunksStatus.reserveSizeWithinRadius
bee_tui_status_storage_radiusStatus.storageRadius
bee_tui_status_committed_depthStatus.committedDepth
bee_tui_status_depth_radius_gapcommittedDepth - storageRadius (synthesised)
bee_tui_status_is_reachable0 / 1
bee_tui_status_is_warming_up0 / 1
bee_tui_status_last_synced_blockStatus.lastSyncedBlock
bee_tui_status_proximityStatus.proximity
bee_tui_status_batch_commitmentStatus.batchCommitment
bee_tui_status_pullsync_rate_per_secondStatus.pullsyncRate (chunks/sec)

Chain (/chain-state)

MetricDescription
bee_tui_chain_blockLocal block height
bee_tui_chain_tipHighest block observed
bee_tui_chain_lag_blockstip - block (synthesised)
bee_tui_chain_current_price_plurPer-chunk PLUR/block price

Postage (/stamps)

bee_tui_stamps_count is unlabelled; the per-batch metrics carry {batch_id, label} so a Grafana panel can graph them per batch.

MetricDescription
bee_tui_stamps_countTotal batches
bee_tui_stamp_worst_bucket_ratioWorst-bucket fill 0..1 (S2's worst-bucket %)
bee_tui_stamp_ttl_secondsPredicted TTL
bee_tui_stamp_depthBatch depth
bee_tui_stamp_capacity_bytes2^depth × 4096
bee_tui_stamp_immutable0 / 1
bee_tui_stamp_usable0 / 1 (chain-confirmed)

Pending transactions

MetricDescription
bee_tui_pending_tx_countNumber of pending Bee transactions
bee_tui_pending_tx_oldest_age_secondsAge of the oldest pending tx

bee-tui's own client-side requests

Same window as the S8 RPC/API screen.

MetricDescription
bee_tui_self_request_sample_sizeEntries contributing to the percentile math
bee_tui_self_request_latency_p50_secondsMedian latency (omitted when no samples)
bee_tui_self_request_latency_p99_seconds99th-percentile latency
bee_tui_self_request_error_ratioFraction 0..1 with status ≥ 400

SWAP / Lottery / Topology / Network

MetricDescription
bee_tui_swap_chequebook_total_plurTotal chequebook balance (PLUR)
bee_tui_swap_chequebook_available_plurUncashed balance (PLUR)
bee_tui_lottery_staked_plurCurrently staked BZZ in PLUR
bee_tui_topology_populationPeers known across all bins
bee_tui_topology_connectedCurrently connected peers
bee_tui_topology_depthKademlia depth
bee_tui_topology_radiusNearest-neighbour low watermark
bee_tui_network_underlay_countUnderlay multiaddr count from /addresses

Wire format

Content-Type: text/plain; version=0.0.4; charset=utf-8 — the standard Prometheus text exposition format. Each metric family emits a # HELP and # TYPE line followed by one sample line. Label values are escaped per the Prometheus spec (\\, \", \n).

Security notes

  • Default bind is 127.0.0.1. If you set addr = "0.0.0.0:...", you've opted into reachability from any interface — put a firewall in front.
  • The endpoint exposes batch IDs and the node's overlay address. These are public on-chain values but worth knowing if you proxy the endpoint through a reverse proxy you don't control.
  • No authentication. Prometheus's standard answer is to bind scrapers behind a private network or use mTLS at the proxy layer.