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

How to Get the Current Block Number from an EVM or Solana RPC

A reproducible guide to reading the latest block number from an RPC endpoint, verifying it, and diagnosing stale or mismatched results.

TL;DR

The block number is the canonical position of a block in a chain's history, and every JSON-RPC provider exposes it through a small set of methods. On EVM chains you call eth_blockNumber; on Solana you read getSlot or getBlockHeight; on other networks the method name differs but the pattern is the same. This article shows runnable calls, explains what the returned value actually represents, and gives a measurement procedure for confirming that the number you receive is fresh and consistent. It also covers the common reasons a block number looks stale, jumps, or disagrees between two endpoints.

What the block number represents and why it matters

A block number is a monotonically increasing integer that identifies a block's position in a chain. On EVM networks the genesis block is block 0, and each subsequent block increments the number by one. The latest block number is therefore a proxy for how far the chain has advanced and how current your RPC view is.

Applications use the block number for many things: pinning a query to a consistent state with eth_call at a specific block, deciding whether a transaction has been included, computing confirmation depth, or detecting that an indexer has fallen behind. Because the number is cheap to fetch, it is also the standard health check for an RPC connection.

The important nuance is that "latest block number" is not a single global truth at a given instant. Different nodes learn about new blocks at slightly different times, and load-balanced endpoints may route consecutive requests to different backends. Treat the value as a sampled observation, not an exact clock.

  • EVM: eth_blockNumber returns the latest block height as a hex quantity.
  • Solana: getSlot returns the current slot; getBlockHeight returns the height of the last confirmed block.
  • Other chains: method names vary, but the concept is a head height or slot number.

Prerequisites and assumptions

You need an HTTP or WebSocket RPC URL for the network you are querying. This guide uses the placeholder RPC_URL; substitute the endpoint you have been issued. For a managed endpoint, see the OnFinality API service and the supported networks list.

The examples assume a JSON-RPC interface reachable over HTTPS. EVM examples use standard Ethereum JSON-RPC methods, which are implemented by most EVM-compatible chains. Solana examples use its JSON-RPC API. No private key is required to read a block number; these are public read methods.

If you are choosing between providers rather than writing code, the concrete endpoint recommendation belongs in RPC Assistant. This article focuses on the method, the verification procedure, and the failure modes.

Getting the block number on EVM chains with curl

The simplest EVM call is eth_blockNumber. It takes no parameters and returns a hex-encoded quantity. The following command is runnable once you replace RPC_URL:

  • A successful response looks like {"jsonrpc":"2.0","id":1,"result":"0x..."}.
  • The result field is a hex string; convert it to decimal before comparing or storing it.
  • An error object instead of result usually means the method is unsupported or the request was malformed.
curl -s -X POST "$RPC_URL" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

Getting the block number in JavaScript and Python

In application code you will usually wrap the call in a small helper. The JavaScript example below uses the built-in fetch available in modern Node.js and browsers, and converts the hex result to a number:

const RPC_URL = process.env.RPC_URL;

async function getBlockNumber() {
  const res = await fetch(RPC_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'eth_blockNumber',
      params: []
    })
  });
  const json = await res.json();
  if (json.error) throw new Error(json.error.message);
  return Number.parseInt(json.result, 16);
}

getBlockNumber().then(console.log).catch(console.error);

Getting the block number on Solana

Solana does not use eth_blockNumber. The closest equivalents are getSlot, which returns the current slot the node is processing, and getBlockHeight, which returns the height of the last confirmed block. Slots and block heights are related but not identical: slots can be skipped, so block height advances more slowly than slot number.

Use getSlot when you need the current position of the cluster, and getBlockHeight when you need a confirmed height suitable for indexing or confirmation logic. The curl call below uses getSlot:

  • The commitment parameter controls which cluster state you observe; confirmed and finalized behave differently under fork conditions.
  • getBlockHeight accepts the same commitment options and returns a number rather than a slot.
  • Do not compare a Solana slot directly to an EVM block number; they are different units.
curl -s -X POST "$RPC_URL" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"getSlot","params":[{"commitment":"confirmed"}]}'

Verifying that the block number is fresh

A returned number is only useful if it is current. The reliable way to check freshness is to sample the same endpoint twice with a known interval and compare the delta against the chain's expected block time. The procedure below produces a results table you can fill in with your own observations; do not assume any values in advance.

Run the sampling script against each endpoint you are evaluating, at the same time, for the same duration. Record the first block number, the last block number, the elapsed seconds, and the computed blocks-per-second. Then compare that rate to the network's documented target block time. A large shortfall indicates a lagging node or a throttled endpoint.

  • | Endpoint | First block | Last block | Elapsed (s) | Blocks/s | Notes |
  • |----------|-------------|------------|-------------|----------|-------|
  • | RPC_URL A | | | | | |
  • | RPC_URL B | | | | | |
import os, time, requests

RPC_URL = os.environ["RPC_URL"]
INTERVAL = 5
SAMPLES = 12

def block_number():
    p = {"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}
    r = requests.post(RPC_URL, json=p, timeout=10).json()
    return int(r["result"], 16)

first = block_number()
start = time.time()
for _ in range(SAMPLES):
    time.sleep(INTERVAL)
    last = block_number()
elapsed = time.time() - start
print({"first": first, "last": last, "elapsed_s": round(elapsed, 1),
       "blocks_per_s": round((last - first) / elapsed, 3)})

Cross-checking two endpoints for consistency

A single endpoint can be internally consistent but still wrong relative to the rest of the network. To detect this, query two independent endpoints within a short window and compare their block numbers. A small difference is normal propagation delay; a large or growing difference suggests one endpoint is lagging.

For EVM chains, you can also confirm the block number against a block header: call eth_getBlockByNumber with the latest tag and check that the returned number field matches what eth_blockNumber reported. If they disagree, the endpoint may be load-balancing across backends at different heights.

  • Compare the number field in the block object with the eth_blockNumber result.
  • Check the block timestamp to estimate how old the head is.
  • Repeat the comparison a few times to see whether the gap is stable or widening.
curl -s -X POST "$RPC_URL" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["latest",false]}'

Troubleshooting stale, missing, or mismatched block numbers

When the block number looks wrong, work through the causes in order of likelihood. Most incidents are configuration or rate-limit issues rather than chain problems.

If eth_blockNumber returns an error, confirm the method name and that the endpoint is for the correct network. A method that works on Ethereum may be absent on a non-EVM chain. If the call succeeds but the number never changes, the endpoint may be serving cached responses or the node may be behind. If the number jumps by an unexpected amount, you may be hitting a load balancer that routes to different backends, or the chain may have had a period of rapid block production.

  • HTTP 429 or provider-specific rate-limit errors: slow down requests or use a dedicated endpoint.
  • Timeouts: add explicit client timeouts and retries with backoff.
  • Hex parsing errors: ensure you convert with base 16, not base 10.
  • Solana slot vs block height confusion: pick the method that matches your confirmation semantics.
  • WebSocket subscriptions: a dropped connection can leave you with a stale cached number; resubscribe and re-fetch on reconnect.

Limitations and tradeoffs of block-number checks

The block number is a coarse health signal. It tells you the chain is advancing but not that the endpoint is correct, complete, or fast for other methods. A node can report a current block number while failing eth_call or returning inconsistent state for archive queries.

Sampling frequency is also a tradeoff. Polling every second gives finer resolution but consumes rate-limit budget and may itself distort measurements on constrained endpoints. For production monitoring, a moderate interval combined with alerting on sustained lag is usually more useful than high-frequency polling.

Finally, block numbers are chain-specific. A number that is valid on one network means nothing on another, so always pair the value with the network identifier and the method used to obtain it.

Next steps for production use

Once you can read and verify a block number, the next step is to build it into your application's health checks and indexing logic. Store the block number alongside any state you persist, so you can detect gaps and reorgs later. For workloads that need consistent head-of-chain access, consider a dedicated node rather than shared public endpoints.

If you are comparing providers or need a concrete endpoint for a specific network, use RPC Assistant for the short recommendation and keep this article as the verification methodology. For capacity planning and cost, review the RPC pricing and the broader RPC endpoints guide.

  • Log block numbers with timestamps to build a lag baseline.
  • Alert when the observed rate falls below a threshold you derive from your own measurements.
  • Re-verify after any provider or network change.

Never Worry about Infrastructure Again

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

Get Started