UpgradesSeptember 14, 2026by
EmpoorioChain Core
EmpoorioChain Core

Finality Under the Microscope: How GRANDPA Latency Is Measured and What Was Found

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_seconds at latest, p50, p95, p99
  • empoorio_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:

p50p95p99
Inclusion3.51 s4.20 s4.26 s
Finality16.96 s17.66 s17.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.

Share this article