The Analytics screen reads a single procedure, analytics.summary, and renders it without further aggregation. Everything on the screen is therefore a direct projection of that response. This page defines what each field measures, how the series are bucketed, and how to read the colour bands. The screen only renders once the BDN is deployed. Until mod_bdn / mod_solana_tpu nodes are running and transport metrics are being collected, you get the pending state instead of charts, because there is no series to draw.

The 24-hour window and bucket size

analytics.summary takes no input. It serves a fixed 24-hour window. The screen header states this (last 24h) and there is no range selector — an earlier 1h/24h/7d control was removed because it did not change the procedure’s response, and a control that does not move the data is a lie. The response carries plain arrays, not timestamped points. Index 0 is the oldest bucket and the last index is the most recent. The charts label the axis −24h · −18h · −12h · −6h · now (fan-out uses −24h · −16h · −8h · now), so the bucket width is whatever divides the 24-hour window into array.length buckets. Read bucket size as 24h ÷ series length rather than assuming a fixed interval — different series in the same response may have different lengths, and the CSV export explicitly handles that (see below). Series that FirstByte has no samples for come back empty. The screen renders — for the fan-out peak, and the leader / region / feed lists render their own empty copy rather than a zero row.

How land rate and land latency are measured

Land rate is the percentage of submitted transactions that landed. It arrives as two parallel series under landRate: Both are plotted on one area chart with a fixed max of 100, so the vertical scale is always the full 0–100% range. The two series are the comparison the screen exists for: BDN path versus direct TPU path over the same window. Land latency is reported in milliseconds as three percentile series under latency: p50, p95, and p99. They are drawn on a shared auto-scaled axis, with p50 filled and p95 / p99 as lines, so the spread between the median and the tail is the thing you read. The percentiles are computed per bucket, not across the whole window — each point is the percentile of the landings in that bucket. There is no fixed target or threshold attached to land rate or latency at the aggregate level. The only banded values on this screen are the per-leader land percentages and the per-track feed freshness comparison.

Fan-out volume and the dedup hit ratio

fanout is a single series sourced from the bdn.tx_fanout counter, expressed as transactions per second across all edges. It is drawn as bars. The value in the card header is the peak of the loaded series, Math.max(...an.fanout) — the highest single bucket in the 24 hours, not an average. dedup describes duplicate suppression: The donut shows hitRatio against its complement (100 - hitRatio), so it is a share-of-total reading, not a gauge against a target. Dedup keys on the first 64 bytes of the transaction — the Solana signature. Two submissions of the same signature, however they arrive and from whichever edge, collapse to one fan-out. That is why a healthy multi-submit strategy shows a non-trivial hit ratio rather than zero: it means the BDN absorbed your retries instead of pushing them onto the leader.

Per-leader and per-region attribution

byLeader is a list of per-validator rows. Each entry carries: The land percent colour bands are applied in the table and are the only per-row health signal on the screen: Leader rows only exist after something has landed. With no landings the table renders a single explanatory row — leader stats appear after the first landed transaction — rather than an empty grid. byRegion is the same data rolled up by region. Each entry has region, landed (absolute count of landings) and share (percent of total landings). The meters are drawn against a max of 26, so a region at 26% or above fills the bar; the numeric share next to it is the authoritative value. Region swatch colours match the per-leader table because both call regionColor, so you can trace a hot region down to the leaders inside it.

Feed freshness targets and breach handling

feedSlo is a per-track list comparing observed feed latency against that track’s target. Each entry has: The row renders actual / target in milliseconds followed by a pill: in SLO when ok is true, breach when it is false. The targets are per-track and come from the procedure — the screen does not hardcode a number, and neither should your alerting. Read target from the response if you mirror this comparison elsewhere. ok is the authoritative breach signal. Do not recompute it by comparing actual to target yourself; the procedure owns the comparison, and the pill follows ok exactly. With no samples, the card explains that the SLO fills in once the private feed is subscribed. An unsubscribed feed produces no rows, which is distinct from a feed that is subscribed and breaching.

The CSV export format

Export CSV in the page header serialises the series that are already loaded in the browser — it does not re-query. The file is named bdn-analytics-24h.csv. The row count is the longest of the exported series:
One row per bucket, with these columns in order: Where a series is shorter than n, the cell is written empty rather than 0. An empty cell means “no sample in this bucket for this series”, and treating it as a zero will skew any average you compute downstream. If every series is empty you get a header-only file — the export reports the absence of data honestly instead of fabricating rows. Note what is not in the export: the dedup ratio, the per-leader table, the per-region breakdown and the feed SLO rows are screen-only. Only the three time-bucketed families (land rate, latency percentiles, fan-out) are exported, because only they share the bucket index that the CSV is keyed on.