· nibiru · 14 min read
Where a 1.5-second block spends its time
Profiling Tendermint on Nibiru: the wait between heights, the cost of voting, and what a different ordering architecture might change.
Research note by Unique Divine · Nibiru production capture, October 17 to 19, 2026 · All times UTC
I started this investigation with a practical question: what would make a Sai transaction feel faster? Nibiru produces blocks roughly every 1.5 seconds, and its committed blocks carry Byzantine fault tolerant, or BFT, finality. I want the application to feel responsive while making clear what each response guarantees.
That 1.5 seconds is the measured mean interval between blocks. It is not a submission-to-finality measurement. A transaction can wait for inclusion, and RPC, indexing, or application updates can add delay after consensus has decided its block.
Before choosing an architecture, I wanted a budget for the time we already spend. This note uses a 48-hour production capture, observations from a voting validator and two nonvoting nodes, and the histories of two chain upgrades. It describes measured behavior and possible experiments.
The promising result is how much of that interval sits in two places. Removing the measured NewHeight interval and both voting intervals, while holding everything else fixed, leaves 267.70 ms, roughly a quarter of a second. The four-scenario table shows the arithmetic. That gives me a concrete reason to test shorter scheduling and a different ordering architecture. It is a calculation from real phase measurements, not an achieved confirmation time or proof that every subtracted cost can disappear.
The headline numbers describe the voting validator. Each node observes the same chain, so their interval counts do not add together. The observed application load was about 1.33 delivered transactions per second on each observer. This is a low-load cadence baseline, not a measurement of maximum throughput.
A block needs agreement, execution, and delivery.
The proposer supplies a candidate block containing ordered transactions. Validators exchange prevotes and precommits before committing it. Each executing node applies the block to its application state and persists the result. RPC and indexer services then expose results to the application.
Those are different confirmation boundaries. A transaction accepted by an RPC has not necessarily been ordered, executed, or finalized. For trading UX, I care about when the user can see and act on the executed outcome, as well as what guarantee backs that outcome.
What the phases mean
A height identifies one block’s place in the chain. A round is an attempt to agree on a block at that height. An unsuccessful attempt leads to another round. Quorums count voting power, rather than a simple count of machines.
| Phase | What the node is doing |
|---|---|
| NewHeight | Waiting for the scheduled start of the next height. This can include the remaining commit-timer wait. |
| NewRound | Preparing a round and its proposer. Configuration can also make this state wait for transactions. |
| Propose | Distributing, receiving, and checking a candidate block with an ordered transaction list. |
| Prevote | Validators vote for a block or nil, following proposal validity and any existing lock. Nil means they do not support a block in that vote. |
| Precommit | After seeing more than two-thirds of voting power prevote a block, validators lock and precommit it. Without that evidence they can precommit nil. |
| Commit | Matching precommits from more than two-thirds of voting power establish the consensus decision. The node obtains the block, executes it, and persists its local state. |
Locks restrict which block a validator can support in later rounds. Together with intersecting quorums, they prevent conflicting decisions while less than one-third of voting power is Byzantine. That is the fault assumption behind BFT finality. Execution and persistence still take time after the quorum decision.
The diagram shows a successful round. Invalid proposals, unavailable proposers, and delayed votes can cause retries. Conditional wait states are omitted, and arrow lengths do not measure transaction latency.
Which nodes I measured
The capture samples one voting validator, rather than the whole voting set. It participates in agreement and can take a turn as proposer. The two nodes labelled snapshot are nonvoting full-node observers. They verify and execute the same chain without adding voting power. The label does not make their measurements a benchmark of snapshot restoration.
Their comparison shows how one chain’s cadence appears from different nodes, and how local processing and observation differ. An observer can receive enough later-stage evidence to advance without visiting every earlier state. Fewer recorded prevotes on an observer do not mean the validator network skipped them.
The largest phase is the wait for the next height.
NewHeight contributes about 61% of the validator’s measured interval. Prevote and Precommit together contribute about 21%. Each phase contains local work and waiting; phase duration does not isolate networking.
Select a node to compare its local view. The snapshots are nonvoting observers, not alternative proposers. The capture does not separate the validator’s proposer heights from its other heights.
Voting validator · 114,057 intervals · 96/96 half-hour bins complete · pooled window complete
NewHeight
922.49 ms per block · 60.89% · 922.50 ms per visitThe remaining scheduled wait before starting the next height. Commit processing has already used part of that schedule.
Full phase table and measurement boundaries
Contribution is the phase-duration counter change divided by block observations. Mean visit divides by phase visits instead. Repeated rounds and skipped states make these different.
| Phase | Mean visit, ms | Per block, ms | Visits/block | Share | Coverage |
|---|---|---|---|---|---|
| NewHeight | 922.50 | 922.49 | 0.999991 | 60.89% | Observed |
| NewRound | 1.68 | 1.68 | 0.999562 | 0.11% | Observed |
| Propose | 187.65 | 187.56 | 0.999562 | 12.38% | Observed |
| Prevote | 165.86 | 165.84 | 0.999912 | 10.95% | Observed |
| PrevoteWait | Unavailable | Unavailable | Unavailable | Unavailable | Absent series |
| Precommit | 159.01 | 159.01 | 1.000000 | 10.50% | Observed |
| PrecommitWait | Unavailable | Unavailable | Unavailable | Unavailable | Absent series |
| Commit | 78.37 | 78.37 | 1.000000 | 5.17% | Observed |
Actual scrape endpoints: 2026-10-17T04:01:17.125000Z to 2026-10-19T04:01:17.125000Z. Requested window: 2026-10-17T04:02:00.000000Z to 2026-10-19T04:02:00.000000Z. Signed residual +0.08 ms. Each boundary uses the preceding scrape, at most 90 seconds earlier.
NewRound itself contributes only 1.68 ms per block on the validator. Propose contributes 187.56 ms. Those averages establish neither a 250 ms ceiling nor a complete agreement-and-execution path. The roughly 268 ms figure below comes from a different calculation across the entire phase budget.
The 96 half-hour bins partition the capture. Their means are relatively consistent, but their distribution is not an individual-block p50, p95, or p99. The available histogram buckets are too coarse to establish precise subsecond tail percentiles.
What would remain if we removed the wait and voting?
The validator averages 1,515.04 ms per block. NewHeight contributes 922.49 ms, and Prevote plus Precommit contributes 324.85 ms. Subtracting both leaves 267.70 ms, about an 82% reduction in this fixed-cost model.
1,515.04 − 922.49 − 324.85 ≈ 267.70 ms remaining. Measured phase costs; hypothetical removal. All other contributions and the signed residual stay fixed.
Scenario table · voting validator
| Scenario | Interval, ms | Evidence status |
|---|---|---|
| Captured baseline | 1,515.04 | Measured |
| Zero remaining NewHeight wait | 592.55 | Hypothetical |
| Zero Prevote and Precommit | 1,190.19 | Hypothetical |
| Zero NewHeight and both voting phases | 267.70 | Hypothetical |
The first row is measured. Each other row sets the named phase contributions to zero and keeps everything else, including Commit processing and the signed residual. The table follows the node selected above.
This separates two experiments. Reducing the next-height schedule could shorten cadence while retaining voting. A trusted sequencer could change the agreement path and remove its distributed voting exchange. The combined row asks what would remain if both changes removed their measured intervals completely.
The remaining work may change under either experiment. Validation, replication, signing, and persistence can retain or replace part of the subtracted costs. The table is an opportunity estimate, not a throughput forecast or an end-to-end transaction latency benchmark. It makes the potential large enough to test against representative application load and an explicit confirmation guarantee.
Commit processing uses part of the next-height schedule.
CometBFT v0.37.18 schedules the next height when it enters Commit. Application execution and persistence consume some of that interval. NewHeight contains the remaining wait. The validator’s Commit and NewHeight contributions total 1,000.86 ms per block.
The validator has a shorter Commit and a longer NewHeight than the observers. Their combined means are similar. These are pooled observations, not paired per-block traces or proof that a database difference explains the whole split.
The configuration source describes the commit wait as time to receive additional precommits after quorum. Its default is one second. The state implementation sets the next start time from Commit entry plus that configured interval. I have not independently retrieved the live timeout setting.
Reducing this wait is a candidate for shorter blocks while retaining voting. The version also supports skip_timeout_commit, which can start the next height early after all precommits arrive. That is a stronger condition than a quorum. Lowering failure timeouts is a separate change and does not automatically speed up already-successful voting phases.
The wait precedes the next height. It need not delay exposing an already executed result from the previous block. Shorter cadence can reduce how long newly arriving transactions wait for their next inclusion opportunity, while repeating block-level work more frequently. The experiment needs to measure both effects.
Blocks resume before the phase budget settles.
The initial upgrade interruption lasts seconds. Elevated Propose and Precommit contributions continue after the restart. I keep the initial gap and the recovery tail separate because they answer different operational questions.
46.14 seconds
Largest canonical header interval, at H+2. Header time derives from previous-height commit votes, so this is not a local halt stopwatch.
Confirmed at +10 h 10 min
The qualifying 30-minute sequence runs from 18:15:12 to 18:45:12 UTC on 2026-09-26.
Upgrade table, including the incomplete transition
| Milliseconds per block | Before −30 to −5 min | Transition −5 to +5 min | Recovery +5 to +30 min | Later +30 to +60 min |
|---|---|---|---|---|
| Block mean | 1,533.02 | 1,946.67 | 2,677.78 | 2,288.03 |
| NewHeight | 912.18 | 886.47 | 881.29 | 902.07 |
| NewRound | 1.78 | 1.80 | 1.65 | 1.72 |
| Propose | 185.94 | 438.01 | 893.84 | 667.02 |
| Prevote | 176.67 | 210.20 | 248.70 | 208.64 |
| PrevoteWait | 0.00 | 0.00 | 0.00 | 0.00 |
| Precommit | 167.74 | 295.07 | 532.64 | 413.75 |
| PrecommitWait | Unavailable | Unavailable | Unavailable | Unavailable |
| Commit | 88.64 | 118.13 | 117.83 | 99.87 |
| Signed residual | +0.07 | -3.02 | +1.83 | -5.05 |
| Coverage | Complete | INCOMPLETE · reset crossing | Complete | Complete |
Proposal 36 · applied height 46,828,562 · anchor 2026-09-26T08:35:12.320886074Z. Transition counters include only observed running segments and exclude reset-crossing pairs. They do not include all stopped time.
Detailed timeline for the selected upgrade
The recovery test requires six consecutive complete five-minute bins within 10% of the pre-upgrade block mean, plus a complete combined window. It is confirmed at the end of that 30-minute sequence. It does not prove permanent recovery or identify the cause of the elevated phases.
The v2.20.0 observation needed an extension to 24 hours after activation because the criterion had not been met at six hours. The v2.21.0 observation met it within the original capture. The detailed figures retain the longer curves rather than showing only selected favorable windows.
A different ordering architecture changes the voting path.
Prevote plus Precommit contributes 324.85 ms per block on the validator. Setting those contributions to zero leaves 1,190.19 ms, if everything else stays fixed. The earlier opportunity table includes the separate NewHeight opportunity and the combined roughly 268 ms scenario.
1,515.04 − 324.85 = 1,190.19 ms in the zero-voting scenario. That subtracts 21.44% of the measured interval. Other contributions and the signed residual stay fixed.
The hypothetical rows retain other work and the signed residual. Removing both Commit processing and the entire shared schedule would double-count an opportunity.
Why can a sequencer avoid the voting exchange?
A sequencer chooses transaction order. Tendermint’s proposer already does that: it supplies a candidate ordered block. The other validators still need to agree which proposal becomes history.
Suppose two transactions compete for the same remaining liquidity. Their order can change the result. A faulty proposer could send different orders to different peers, or disappear before the next leader takes over. Prevotes, precommits, and locks let validators agree on one history through those failures. Knowing an order is not the same as knowing that the other nodes will honor it.
A trusted single-sequencer design changes the authority. Its rules accept one operator’s stream as the canonical order. Replicas follow and verify that stream; the operator does not need a Tendermint quorum to choose each next order. A fast response can therefore skip those voting exchanges because the client trusts the operator, with whatever signing, persistence, or replication the design requires. That response does not carry Tendermint’s quorum guarantee.
There are two different experiments:
- Keep Tendermint and stream provisional results. An ordering service could return an early result while validators still vote on the eventual block. This can improve feedback time without removing the chain’s voting cost. The design must explain how proposals honor that order and how conflicts or rollbacks reach the application.
- Replace the agreement path with trusted sequencing. The operator chooses the accepted order without those validator votes. This can remove voting from the response path, but changes the fault model. Replicas still need data and execution; failover and any later publication or settlement need explicit rules.
A sequencer receipt can acknowledge an order before execution finishes. An executed provisional result says more, but may still precede network finality. A distributed sequencer can itself run BFT and retain quorum communication. The word sequencer alone promises neither fewer messages nor a particular latency.
Evolve’s single-sequencer design is one concrete architecture to investigate. Its ABCI adapter does not make it interchangeable with the application version in this capture. Integration and confirmation semantics need their own investigation.
A small BFT committee is another option. It changes the voting set and can still use CometBFT. Fewer voters and controlled connectivity may reduce coordination cost, but execution and persistence remain. The useful comparison is the latency of the guarantee the application actually needs.
A one-validator run is a control, not the network benchmark.
A single validator satisfies its quorum locally. It still performs local work and may retain configured waiting, but it cannot establish production agreement latency. Comparing it with multiple voters is useful; subtracting the results does not isolate networking exactly because scheduling and other costs can change.
Honest nodes incur network cost even when they agree. A useful experiment suite would separate:
- Multiple honest validators under representative application load, with realistic placement, bandwidth, and latency.
- Controlled delay, loss, outages, partitions, and restarts, followed through recovery and catch-up.
- Faulty proposers, invalid proposals, and conflicting votes, with an explicit distribution of faulty voting power.
Input fuzzing complements controlled fault injection. Failed transactions, invalid blocks, and malformed messages exercise different paths. A valid block can contain a transaction that executes unsuccessfully.
The consensus specification describes additional rounds for failed proposals and delayed votes. CometBFT also has an end-to-end harness to examine before building a new testing system. Healthy and fault-case results should remain separate. Continued progress is not a general expectation once the protocol’s fault threshold is exceeded.
For the application comparison, I would record admission, ordering, execution, durability, and result-delivery boundaries. Latency percentiles, successful throughput, and queue growth matter together. Faster ordering that leaves an ever-growing execution backlog would not meet the user-experience goal.
Each clock answers a different question.
Use counters for phase averages, event logs for local lifecycle events, and block headers for canonical cadence. Their clocks are not interchangeable.
The requested baseline window runs from October 17 at 04:02 UTC through October 19 at 04:02 UTC. Actual validator scrapes run from 04:01:17.125 UTC on the first day to the same time on the last day. The calculations use raw counter changes; they do not extrapolate to nominal boundaries. Adjacent bins share their boundary scrape, keeping their counts consistent with the pooled total.
The phase histograms record elapsed time on state exit. Sixty-second scraping still supports millisecond means from duration sums and counts. It does not provide a millisecond trace of each block. The sampled event logs have whole-second precision and cannot resolve a 150 ms voting phase.
A stopped process records no phase time. Restart-crossing counter pairs are excluded and transition tables remain incomplete. Missing series mean unavailable, not zero. A negative residual stays negative rather than being drawn as extra positive time.
The inspected release tags v2.20.0, v2.21.0, and v2.21.2 pin CometBFT v0.37.18. Startup logs identify app 2.21.0 on the baseline validator and 2.21.2 on the observers. This is version evidence, not a cryptographic attestation of each running binary.
Fast blocks and finality measure different things.
Block cadence is how often blocks appear. Confirmation is a protocol or application’s chosen confidence level. Finality prevents reversal under the protocol’s security assumptions. Verified execution and external settlement can add further boundaries. These background examples were checked October 19, 2026; the Nibiru capture does not measure them.
- Monad documents 300 ms blocks, 300 ms speculative finality, and 600 ms consensus finality. Its later
Verifiedstage confirms the execution state root atT+5, about 1.5 seconds after proposal at that cadence. Its guidance asks exchanges and bridges to wait for that stage. Consensus finality itself is faster than Nibiru’s measured block interval. 1 - Solana distinguishes block production from TowerBFT finalization across subsequent slots. Its Alpenglow page describes a roughly 150 ms finality target, with mainnet activation still pending as of this review. That target is not a measured current-mainnet result. 2
- Hyperliquid says order-response latency includes API transport, mempool inclusion, and commitment, usually across two pipelined HyperBFT blocks. Its input-streaming option exposes transactions before execution results exist. Earlier information and a committed outcome are distinct products. 3
- OP Stack rollups distinguish sequencer-backed feedback from Ethereum-backed finality. OP Mainnet’s guide describes soft confirmation around two seconds, while hard finality typically takes 15 to 30 minutes after submission. Rollups do not share one universal finality delay. 4
Pipelining lets work on successive blocks overlap. A short interval between blocks can coexist with several voting stages for each block. Each comparison needs a start event, an end event, and the guarantee that end event provides.
Make the result arrive when it is useful.
For Sai, I would first measure the path from submission to inclusion, consensus decision, execution, and the visible application update. The phase budget does not tell me how much time RPC polling, indexing, or rendering adds.
A finalized, executed result should reach the user promptly. It does not need to wait for the next-height timer to expire. Shorter scheduling can reduce inclusion waits. An ordering service could offer earlier provisional feedback, provided that the interface distinguishes receipt, promised order, provisional execution, and final confirmation. A received transaction has not yet established a trade.
That gives the roughly 268 ms opportunity a practical purpose. I want to test which costs can shrink, which guarantee a response carries, and when the user can act on it. If provisional state changes, the application needs to reconcile it visibly rather than presenting an early estimate as a finalized position.
Background reading
- Monad developer summary, especially Timing considerations and Asynchronous Execution.
- Solana Alpenglow overview, including the dated activation status and distinction between block time and finality.
- Hyperliquid latency guide, especially pipelined commitment and streaming inputs before execution.
- OP Stack transaction finality, covering sequencer trust, data publication, and Ethereum finality.
Unique Divine


