Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions benchmarks/l1-finality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ seo_title: "Fastest L1 finality 2026"
seo_description: "Fastest L1 finality live across 11 chains: Gram, SUI, Hedera, Stellar, Solana, Ethereum and more."
subtitle: Wall-clock seconds from latest block to the finalized block on Ethereum, Solana, Gram, SUI, Stellar and 5 more chains, refreshed every 10 seconds.
seo_intro: |
This page measures L1 finality time live for every major Layer-1 blockchain, with p50 / p90 / p99 refreshed every 10 seconds. Stellar finality time is ~5 seconds, the close interval the Stellar Consensus Protocol locks in via federated Byzantine agreement. Solana finality time goes from sub-second on the processed commitment to ~12.8 s on finalized after 32 confirmed slots. Ethereum finality time is ~12.8 minutes, the 2-epoch Casper FFG window. Hedera finality time clears in 3-5 seconds via Hashgraph aBFT. SUI finality time and Gram finality time (formerly TON) both sit under one second via Mysticeti DAG-BFT and BAG consensus. BNB and Avalanche finality time land near two seconds through fast-finality forks. Probabilistic chains (Litecoin, Monero) settle on a confirmation-depth convention measured here in minutes.
This page measures L1 finality time live for every major Layer-1 blockchain, with p50 / p90 / p99 refreshed every 10 seconds. Stellar finality time is ~5 seconds, the close interval the Stellar Consensus Protocol locks in via federated Byzantine agreement. Solana finality time goes from sub-second on the processed commitment to ~12.8 s on finalized after 32 confirmed slots. Ethereum finality time is about 12.8 minutes in the ideal case, the 2-epoch Casper FFG window; observed wall-clock finality runs longer, and the table below shows the live measurement. Hedera finality time clears in 3-5 seconds via Hashgraph aBFT. SUI finality time and Gram finality time (formerly TON) both sit under one second via Mysticeti DAG-BFT and BAG consensus. BNB and Avalanche finality time land near two seconds through fast-finality forks. Probabilistic chains (Litecoin, Monero) settle on a confirmation-depth convention measured here in minutes.

faq:
- q: "What is blockchain finality?"
a: "Blockchain finality is the point at which a confirmed transaction cannot be reversed without breaking the protocol's security assumptions. Two finality models exist. Deterministic finality (Ethereum Casper FFG, Stellar SCP, Hedera Hashgraph) reaches an explicit consensus commitment that the network treats as irreversible. Probabilistic finality (Bitcoin, Litecoin, Monero, Cardano) leaves a non-zero reorg probability that decreases exponentially with confirmation depth. This benchmark measures the wall-clock time each chain needs to reach its native finality threshold."
- q: "Probabilistic vs deterministic finality, what is the difference?"
a: "Deterministic finality is a binary state. A block is either finalized or it is not, and finalized blocks cannot be reorganized. Probabilistic finality is a confidence curve: a block becomes more final with each confirmation that builds on top of it. Exchanges set a convention (Bitcoin 6, Litecoin 6, Monero 10, Cardano 15) past which they treat funds as settled, but the protocol itself never declares strict finality. This benchmark uses each chain's native convention rather than imposing a uniform depth across all chains."
- q: "What is Ethereum finality time?"
a: "Ethereum finality time is {{p50:ethereum}} (p50, 24h). That is 2 epochs of 32 slots of 12 seconds each, the window Casper FFG needs to justify and finalize a checkpoint. The benchmark measures it live by polling eth_getBlockByNumber(\"latest\") and eth_getBlockByNumber(\"finalized\") every 10 seconds and taking the timestamp delta."
a: "Ethereum finality time measured live on this page is {{p50:ethereum}} (p50, 24h). Casper FFG finalizes a checkpoint two epochs after it is justified, where each epoch is 32 slots of 12 seconds, about 12.8 minutes in the ideal case. Observed wall-clock finality runs longer because a block lands mid-epoch and waits before the two-epoch countdown starts. The live table above shows the measured value. The benchmark polls eth_getBlockByNumber(\"latest\") and eth_getBlockByNumber(\"finalized\") every 10 seconds and reports the timestamp delta."
- q: "What is Solana finality time?"
a: "Solana exposes two commitments. Processed is optimistic and lands sub-second, typically under 500 ms. Finalized requires 32 confirmed slots and clocks {{p50:solana}} (24h average). The leaderboard value is finalized, the stricter guarantee. Sub-second Solana finality is real but only at the processed commitment level, not finalized."
- q: "What is SUI finality time?"
Expand All @@ -29,15 +29,15 @@ faq:
- q: "What is BNB Chain finality time?"
a: "BNB Smart Chain finalizes via the BEP-126 fast-finality fork, dropping the confirmation depth that legacy probabilistic chains require. p50 sits at {{p50:bnb}} (24h), measured via persistent WebSocket subscription that records T1 when block N first appears as latest and T2 when it crosses the finalized threshold."
- q: "Which blockchain has the fastest finality time?"
a: "Sub-second BFT chains lead. Gram and SUI both clock under one second on this live benchmark. BNB and Avalanche sit around one to two seconds via their fast-finality forks. Solana finalized lands around 12.8 s, Ethereum at 12.8 min, and probabilistic chains (Litecoin, Monero) trail at 15 to 30 minutes by confirmation-depth convention."
a: "Sub-second BFT chains lead. Gram and SUI both clock under one second on this live benchmark. BNB and Avalanche sit around one to two seconds via their fast-finality forks. Solana finalized lands around 12.8 s, Ethereum finalizes in minutes (about 12.8 in the ideal case, longer as observed; the live table shows the current p50), and probabilistic chains (Litecoin, Monero) trail at 15 to 30 minutes by confirmation-depth convention."
- q: "How is L1 finality time measured on this page?"
a: "Two methods, picked per chain. RPC pollers compare latest vs finalized block timestamps every 10 seconds, used for Ethereum, Solana, TRON, Stellar, SUI, Gram, Litecoin, Monero. WebSocket subscribers record wall-clock time T1 when a block first appears on the head stream and T2 when it crosses the finality threshold, giving millisecond-precision lag for sub-poll chains (BNB, Avalanche)."

per_chain_explainer:
- slug: ethereum
h2: "Ethereum finality time"
body: |
Ethereum finality time is {{p50:ethereum}} (p50, 24h). Casper FFG finalizes a checkpoint two epochs after it is justified, where each epoch is 32 slots of 12 seconds, the documented 12.8-minute target. Finality is deterministic once reached, but reorgs of unfinalized blocks remain possible inside the two-epoch window. Measured by polling `eth_getBlockByNumber("finalized")` against `latest` every 10 seconds and reporting the timestamp delta.
Ethereum finality time is {{p50:ethereum}} (p50, 24h), measured live. Casper FFG finalizes a checkpoint two epochs after it is justified, where each epoch is 32 slots of 12 seconds, which puts the ideal case at about 12.8 minutes. Observed wall-clock finality runs longer because a block lands mid-epoch and waits before the two-epoch countdown starts. Finality is deterministic once reached, but reorgs of unfinalized blocks remain possible before finalization. Measured by polling `eth_getBlockByNumber("finalized")` against `latest` every 10 seconds and reporting the timestamp delta.
- slug: solana
h2: "Solana finality time"
body: |
Expand Down Expand Up @@ -121,7 +121,7 @@ methodology:

findings:
- "{{name:sui}} returns {{p50:sui}} (p50, 24 h), matching its Mysticeti DAG BFT design. The chain exposes ms timestamps so the measurement is genuinely sub-second."
- "{{name:ethereum}} sits at {{p50:ethereum}} (24 h average), aligned with the 2-epoch finalization spec (32 slots × 12 s × 2)."
- "{{name:ethereum}} sits at {{p50:ethereum}} (24 h average), consistent with the 2-epoch Casper FFG design (32 slots × 12 s × 2 = 12.8 min ideal) plus the mid-epoch wait before the countdown starts."
- "{{name:tron}}'s solidity confirmation hovers around {{p50:tron}}, exactly the documented 20-block delay at 3 s blocks."
- "{{name:litecoin}} and {{name:monero}} sit at {{p50:litecoin}} and {{p50:monero}} (24 h average) by construction, set by the chosen confirmation depth."
- "{{best_name}} currently leads the leaderboard at {{best_p50}} (p50, 24 h) across {{count}} measured L1s. {{worst_name}} trails at {{worst_p50}}."
Expand Down Expand Up @@ -242,7 +242,7 @@ providers:
- slug: ethereum
name: Ethereum
tag: Casper FFG, 2-epoch finalization
formula: "Mean elapsed time (in ms) between `eth_getBlockByNumber(\"latest\")` and `eth_getBlockByNumber(\"finalized\")` timestamps, the 2-epoch Casper FFG window (~12.8 min), over 24h."
formula: "Mean elapsed time (in ms) between `eth_getBlockByNumber(\"latest\")` and `eth_getBlockByNumber(\"finalized\")` timestamps, the 2-epoch Casper FFG window plus intra-epoch wait, over 24h."
queries:
p50: avg_over_time(l1_finality_lag_seconds{chain="ethereum"}[24h]) * 1000
p90: quantile_over_time(0.90, l1_finality_lag_seconds{chain="ethereum"}[24h]) * 1000
Expand Down
31 changes: 26 additions & 5 deletions harnesses/l1-finality/cmd/script/stellar_ws.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ type stellarLedgerEvent struct {

func StartStellarWallClock() {
go func() {
backoff := 2 * time.Second
const baseBackoff = 1 * time.Second
backoff := baseBackoff
cursor := "now"
var lastSeen time.Time
var lastSeq int64
Expand All @@ -44,10 +45,28 @@ func StartStellarWallClock() {
if nextCursor != "" {
cursor = nextCursor
}
if err != nil {
fmt.Printf("[L1][stellar] SSE error: %v (reconnecting in %v)\n", err, backoff)
wallClockHealth.WithLabelValues("stellar").Set(0)
if err == nil {
// Graceful close. Horizon force-closes every SSE
// connection after ~10s with `event: close` and expects
// the client to reconnect using cursor=<last_id>. That is
// the protocol working as designed, not a failure.
// Reconnect quickly and keep the backoff at its floor.
//
// BUG HISTORY (why the Stellar row went dead): the
// previous loop treated every stream end as an error and
// doubled the backoff without ever resetting it, so
// within a minute of startup it slept 64s between ~10s
// connection windows. During each window the replayed
// ledgers failed the 6s liveness filter and the first
// live event exceeded the 30s sanity bound, so the gauge
// almost never received a sample and last_over_time on
// the page eventually returned nothing.
backoff = baseBackoff
time.Sleep(baseBackoff)
continue
}
fmt.Printf("[L1][stellar] SSE error: %v (reconnecting in %v)\n", err, backoff)
wallClockHealth.WithLabelValues("stellar").Set(0)
time.Sleep(backoff)
if backoff < 60*time.Second {
backoff *= 2
Expand Down Expand Up @@ -156,5 +175,7 @@ func runStellarSSE(cursor string, lastSeen *time.Time, lastSeq *int64) (string,
if err := scanner.Err(); err != nil {
return lastID, fmt.Errorf("scan: %w", err)
}
return lastID, fmt.Errorf("stream closed")
// Clean EOF: Horizon's routine ~10s force-close. Not an error; the
// caller reconnects immediately with the returned cursor.
return lastID, nil
}
Loading