Finality is the promise a chain makes to a merchant: this cannot be undone. Measuring how long that promise takes to arrive is more informative than any throughput figure. This post is how EmpoorioChain measures it and what the measurement said.
The instrument
scripts/finality_prometheus_exporter.js subscribes to finalized heads on a node and records the time between consecutive ones. It exports:
empoorio_finality_secondsatlatest,p50,p95,p99empoorio_finalized_head(height)empoorio_finalized_head_age_seconds(how stale the finalized head is right now)empoorio_finality_exporter_up
Prometheus scrapes it (monitoring/prometheus.yml). Every benchmark under load is required to report inclusion and finality at p50/p95/p99 alongside sent, included, finalized counts, failure rate and any observed fork.
What was measured
Mixed-load run, 30 May 2026, 700 transactions:
| p50 | p95 | p99 | |
|---|---|---|---|
| Inclusion | 3.51 s | 4.20 s | 4.26 s |
| Finality | 16.96 s | 17.66 s | 17.72 s |
Failure rate 0.00 %. No fork or reorg observed.
Why finality clusters
Notice how tight the finality distribution is: p50 to p99 spans under a second. That is GRANDPA's signature. It does not finalize block by block; validators vote for the highest block they consider valid and the protocol finalizes the highest common ancestor with a two-thirds supermajority — a whole prefix at once. With 6-second blocks, finality lands about three blocks behind the head, almost regardless of how many transactions are in flight. Inclusion, by contrast, is bounded by the slot: within one block interval.
Against the gate
The mainnet gate requires GRANDPA finality p50 < 12 s and p95 < 30 s under real testnet load. The measurement gives p50 ≈ 17 s: p95 passes, p50 does not. Getting p50 under 12 s with 6-second blocks means finalizing within two blocks rather than three — a matter of GRANDPA round timing and validator count, and one of the reasons the four-validator Zombienet run (prepared, unexecuted) matters: finality behaviour with two validators in one rack tells you little about finality with ten across continents.
What a stall looks like
With two validators, GRANDPA needs both. If one restarts, empoorio_finalized_head_age_seconds climbs linearly — 60, 120, 300 — while Aura keeps authoring, so the best block advances and the best–finalized lag opens. Eoonia keeps showing new transactions as included and none as finalized, which is exactly the honest behaviour the three-state model was designed for. When the validator returns, GRANDPA catches up in one burst and the lag collapses. This is why finality, not block production, is the alerting metric.
BEEFY
The runtime also runs BEEFY, which produces compact finality commitments over the MMR for light clients and bridges. Its cadence is independent of GRANDPA's and it is not what Eoonia or EmpooScan display as finality. Eoonia's light-client protocol consumes it; users never see it.
Next measurement
The next finality report will come from the multi-validator run under artificial latency, with the artefact committed under artifacts/performance/testnet/<date>/. Until then, 17 seconds is the number a payments integration should design around.
Based on CONSENSUS_STATUS.md, PERFORMANCE_REPORT.md (2026-05-30) and MAINNET_GATE.md Gate 2.


