Logo
New RPC users get 35% off their first monthView the offer
OnFinality Learn
Performance & Optimization11 min read

Chainspect-Style Blockchain Fundamentals: A Reproducible Methodology for TPS, Finality, and Decentralization Metrics

How to read, reproduce, and sanity-check the blockchain fundamentals dashboards like Chainspect publishes — real-time TPS, block time, finality, and decentralization — using your own RPC calls.

TL;DR

Chainspect is a blockchain fundamentals tracker that publishes real-time TPS, block time, finality, transaction volume, revenue, and decentralization metrics across many networks without paywalls. This article explains the mental model behind those numbers, then shows how to reproduce the core measurements yourself against any RPC endpoint so you can verify a dashboard claim or build your own internal comparison. It covers the difference between real-time and peak TPS, why block time is not finality, how to count transactions from block data, and how to sanity-check decentralization inputs. Every number you see in a dashboard should be traceable to a query you can rerun.

What a blockchain fundamentals tracker actually measures

A fundamentals tracker such as Chainspect aggregates technical signals that are observable from a node: how many transactions a chain is processing right now, how long blocks take to produce, how long until a transaction is irreversible, how much fee revenue the chain generates, and how concentrated validator or stake power is. The value is not any single number but the ability to compare the same metric across networks using one consistent definition.

The important editorial point is that these dashboards are descriptive, not prescriptive. A high real-time TPS figure tells you what a chain is doing this minute; it does not tell you what it can sustain under adversarial load, nor whether the transactions are economically meaningful. Treat every dashboard figure as a hypothesis you can test with your own RPC calls.

  • Throughput: transactions per second, both real-time and peak recorded.
  • Latency: block time and time-to-finality, which are different things.
  • Economics: fees paid, on-chain revenue, and value metrics.
  • Decentralization: validator count, stake distribution, Nakamoto coefficient.
  • Liveness: whether blocks are still being produced at the expected cadence.

Prerequisites and assumptions before you measure

You need an RPC endpoint for each chain you want to compare, ideally one that exposes standard JSON-RPC methods such as eth_blockNumber, eth_getBlockByNumber, and eth_getBlockReceipts. For non-EVM chains the method names differ but the pattern is the same: fetch recent blocks, count transactions, and timestamp them. If you do not already have endpoints, the multi-chain RPC endpoints guide explains how to structure access, and you can compare plans on the RPC pricing page.

Assume your endpoint may be load-balanced across nodes that are slightly out of sync. That is fine for throughput measurement over a window of dozens of blocks, but it will distort single-block latency measurements. For finality-sensitive work, pin to one node or use a dedicated node so you are not silently switching backends mid-measurement.

Finally, decide your window up front. A 60-second window is noisy; a 7-day window smooths out bursts but hides peak behavior. Publish both if you want to be honest about a chain's performance.

The mental model: throughput, block time, and finality are three different clocks

Throughput is a rate: transactions divided by elapsed wall-clock time. Block time is a cadence: the interval between block timestamps. Finality is a guarantee: the point after which a transaction cannot be reverted under the protocol's assumptions. These three clocks move independently. A chain can produce a block every 400 ms and still take 12 seconds to finalize, and a chain can finalize instantly while processing very few transactions per second.

This is why dashboards separate real-time TPS from max recorded TPS. Real-time TPS is a rolling average of actual included transactions. Max recorded TPS is the highest sustained rate observed in some window, which is a historical fact rather than a capacity guarantee. Neither equals theoretical TPS from a whitepaper, which is usually a benchmark under ideal conditions and should be labeled as such.

For finality, the honest measurement is the gap between the block that included your transaction and the block at which the protocol declares it irreversible. On probabilistic-finality chains that gap is a confidence threshold, not a hard boundary, so any single number is a convention you must state.

Runnable procedure: measure real-time TPS from raw blocks

The simplest reproducible TPS measurement fetches the last N blocks, sums their transaction counts, and divides by the timestamp difference between the newest and oldest block. The script below uses a placeholder RPC_URL and works on any EVM-compatible chain. Run it several times across the day to see variance.

Note that transaction counts from block headers include failed transactions on most EVM chains. If you want successful-transaction TPS, you must fetch receipts, which is slower but more accurate for economic comparisons.

import json, urllib.request, time

RPC_URL = "RPC_URL"
WINDOW = 50  # blocks to sample

def rpc(method, params):
    req = urllib.request.Request(
        RPC_URL,
        data=json.dumps({"jsonrpc":"2.0","id":1,"method":method,"params":params}).encode(),
        headers={"Content-Type":"application/json"},
    )
    with urllib.request.urlopen(req, timeout=15) as r:
        return json.load(r)["result"]

head = int(rpc("eth_blockNumber", []), 16)
blocks = []
for n in range(head - WINDOW + 1, head + 1):
    b = rpc("eth_getBlockByNumber", [hex(n), False])
    blocks.append((int(b["timestamp"], 16), len(b["transactions"])))

elapsed = blocks[-1][0] - blocks[0][0]
tx_total = sum(c for _, c in blocks[1:])
tps = tx_total / elapsed if elapsed else 0
print(f"blocks={WINDOW} elapsed={elapsed}s txs={tx_total} tps={tps:.2f}")

Runnable procedure: block time and a finality sanity check

Block time is the mean interval between consecutive block timestamps over your window. It is easy to compute and easy to misread: a chain with variable block production can show a stable average while individual gaps are long. Report the median and the maximum gap alongside the mean so readers can see the tail.

For finality, the portable check is to submit a transaction and poll until the block containing it is at or below the chain's finalized head. The snippet below assumes an endpoint that exposes a finalized block tag; substitute the chain's native finality method where it differs.

async function finalityProbe(rpcUrl, txHash) {
  const call = async (method, params) => {
    const r = await fetch(rpcUrl, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
    });
    return (await r.json()).result;
  };

  const start = Date.now();
  const receipt = await call("eth_getTransactionReceipt", [txHash]);
  const includedIn = parseInt(receipt.blockNumber, 16);

  while (true) {
    const fin = await call("eth_getBlockByNumber", ["finalized", false]);
    const finNum = parseInt(fin.number, 16);
    if (finNum >= includedIn) {
      return { includedIn, finalizedAt: finNum, seconds: (Date.now() - start) / 1000 };
    }
    await new Promise((r) => setTimeout(r, 1000));
  }
}

finalityProbe("RPC_URL", "0xYOUR_TX_HASH").then(console.log);

Results table: what to record and how to present it

Do not publish a single TPS number. Publish a table with the window, sample size, and dispersion so a reader can judge whether the figure is stable. The template below is the minimum honest presentation; fill it with your own measured values, never with borrowed or estimated figures.

ChainWindowBlocks sampledMean TPSMedian block timeMax block gapFinality (s)Notes
Chain A7 daysNmeasuredmeasuredmeasuredmeasuredendpoint pinned
Chain B7 daysNmeasuredmeasuredmeasuredmeasuredreceipts counted

If you are comparing against a public dashboard, record the dashboard's stated window and timestamp next to your own so the two are comparable. A dashboard showing 24-hour TPS and your script showing a 50-block window are not measuring the same thing, and the difference is often larger than the underlying chain variance.

Decentralization inputs and why they are harder to reproduce

Throughput is cheap to measure; decentralization is not. Validator counts, stake distribution, and the Nakamoto coefficient depend on chain-specific state that may not be exposed over standard RPC. Some chains expose validator sets via a dedicated method or a staking pallet query; others require an indexer or a governance dashboard.

When you cannot reproduce a decentralization metric directly, at least verify its inputs. Confirm the validator count against the chain's own staking module, confirm the stake distribution against the same source the dashboard cites, and state the snapshot block. A Nakamoto coefficient computed from stale stake data is a historical curiosity, not a current property.

This is also where dashboards earn their keep: maintaining consistent validator and stake pipelines across dozens of networks is real engineering work. Reproducing it for one chain is feasible; reproducing it for fifty is a product, not a script.

Troubleshooting inconsistent or surprising numbers

If your TPS differs sharply from a dashboard, work through the usual suspects in order. Most discrepancies are definitional, not adversarial.

If your finality probe never resolves, check whether your endpoint supports the finalized tag or whether the chain uses a different finality primitive. If block timestamps look wrong, confirm you are reading the canonical chain and not a fork or a testnet endpoint. If numbers drift between runs, your load balancer is probably routing to nodes at different heights — pin the endpoint.

  • Window mismatch: 50 blocks versus 24 hours versus 7 days.
  • Failed transactions included in header counts but not in successful-TPS counts.
  • L2 or rollup transactions batched into a single L1 transaction.
  • Endpoint lag: your node is behind the head the dashboard is reading.
  • Timestamp source: block timestamp versus local receive time.
  • Testnet or fork endpoint accidentally used instead of mainnet.

Limitations and tradeoffs of dashboard-style metrics

Fundamentals dashboards optimize for comparability, which means they necessarily flatten chain-specific nuance. A single TPS column cannot express that one chain's transactions are simple transfers while another's are contract calls with different gas costs. A single finality column cannot express probabilistic versus deterministic guarantees. These are tradeoffs, not flaws, but you should know which ones you are accepting.

There is also a measurement-versus-meaning gap. High throughput with low fee revenue may indicate subsidized activity; high revenue with low throughput may indicate expensive blockspace. Reading two columns together is more informative than ranking chains on any single metric, and it is the habit that separates analysis from leaderboard-watching.

Finally, real-time dashboards are snapshots. If you need historical trends or reproducible research, capture your own samples on a schedule and store them, rather than relying on a page that updates under you.

Next steps: build your own fundamentals pipeline

Start with one chain and one metric. Run the TPS script on a schedule, write results to a small time-series store, and add block time and finality once the first pipeline is stable. When you expand to multiple chains, standardize the window and the transaction-counting rule before you add networks, otherwise your comparisons will be apples to oranges.

For endpoint selection across the networks you want to track, the networks directory lists supported chains, and the API service describes how to obtain keys and manage rate limits. If you are running your own measurement nodes for consistency, review the blockchain node hosting guide before you commit to infrastructure.

For the concrete question of which endpoint to use for a specific chain, hand that decision to RPC Assistant rather than guessing — the methodology above is endpoint-agnostic, and the endpoint choice should be made on reliability and latency grounds. Once your pipeline is running, you will have something more valuable than a dashboard screenshot: a reproducible record of what each chain actually did, with the queries to prove it.

Never Worry about Infrastructure Again

OnFinality takes away the heavy lifting of DevOps so you can build smarter and faster.

Get Started