Understanding and Handling Nonce in EVM Chains
What is the Nonce
In blockchain networks using the Account Model, the nonce
is number tracking the transactions sent from an address. It functions as a sequence counter that ensures:
- Transactions are processed in order.
- Duplicate or replayed transactions are rejected - dropped from the mempool.
On Ethereum and all EVM-compatible chains, every transaction from an address must have a unique nonce
, starting from 0
and incrementing by 1 with each transaction mined into a block.
How Tatum REST API Handles the Nonce
When submitting transactions through Tatum’s REST API, the nonce parameter appears as "optional". If not specified, our engine queries the blockchain node to assign it automatically.
Warning
Automatic nonce management by Tatum is not suitable for high-throughput or parallel transaction systems. It introduces latency and may lead to race conditions in mempool state. Manually specifying the nonce is strongly recommended in production environments.
Fetching the Correct Nonce
Using Tatum REST API
For standard use cases, you can query the nonce using our v3 endpoints:
Example request:
curl --location 'https://api.tatum.io/v3/ethereum/transaction/count/0x271ebc3C939Db4d0######' \
--header 'x-api-key: {Mainnet_API_KEY}'
//response:
4887 // Current nonce value in decimals. RPC call under the hood, includes "pending" tx in a given node mempool
Using a JSON RPC request
Example:
curl --location 'https://ethereum-mainnet.gateway.tatum.io' \
--header 'x-api-key: {YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc":"2.0",
"method":"eth_getTransactionCount",
"params":[
"0xYourAddress",
"pending" //includes "pending" tx in mempool
],
"id":1
}'
Warning
The flag "pending" includes transactions in the mempool that are not yet mined. This is useful for broadcasting the next tx, but can be unreliable if:
- Prior transactions were dropped and not seen by a specific node.
- Mempool desync or pruning has occurred.
To be deterministic, use the flag "latest
" instead:
curl --location 'https://ethereum-mainnet.gateway.tatum.io' \
--header 'x-api-key: {YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc":"2.0",
"method":"eth_getTransactionCount",
"params":[
"0xYourAddress",
"latest"
],
"id":1
}'
This returns the "nonce
" of the last transaction successfully mined, ensuring your new transaction will not skip over any missing or dropped txs.
Beware of the Nonce Gap
When using "pending
", the node assumes all prior nonces are either mined or still valid in the mempool. If you've broadcasted a tx with nonce=1400
before broadcasting nonce=1399
, and 1399
never made it into the node’s mempool (e.g., dropped or never propagated), your future calls will suggest a higher nonce. This creates a nonce gap where all subsequent txs are stuck behind a missing tx.
Solution:
- Query the latest confirmed nonce:
eth_getTransactionCount
with "latest
" - Resume broadcasting from that value upward.
- Re-broadcast or replace any dropped transactions to unblock higher-nonce transactions.
Designing a Production-Ready Nonce Strategy
If your application sends multiple transactions rapidly, you must manage the nonce internally and build a queueing system.
Core Principles:
- Track both confirmed and pending nonces.
- Avoid relying on a node’s view of the mempool for critical nonce state.
- Retry dropped transactions with the same nonce.
- Verify status of each broadcasted transaction using
eth_getTransactionReceipt
.
Transaction Status Outcomes
Tx Type | Included in Block | Status | Nonce Reusable? |
---|---|---|---|
Native Asset | ❌ | — | ✅ |
Native Asset | ✅ | 0x0 (Failed) | ❌ |
Smart Contract | ✅ | 0x0 (Revert) | ❌ |
Dropped / Not Mined | ❌ | — | ✅ |
Example: Recovery from a Stuck Transaction
Let’s say your last confirmed transaction used nonce 1377
, but your app broadcasted by mistake1380
directly. Now 1378
and 1379
are missing, and 1380+
are stuck in the mempool.
Solution:
- Fetch the last mined nonce:
eth_getTransactionCount
with "latest
" →1377
- Manually broadcast tx
1378
,1379
,1380
in order. - Monitor tx receipts to confirm mining.
Best Practices for Nonce Handling
- ✅ Use "
latest
" to base your own nonce queue logic. - ❌ Don’t rely solely on "
pending
" unless your tx history is 100% controlled. - ✅ Verify each transaction after broadcasting using
eth_getTransactionReceipt
. - ⚠️ Build retry and reconciliation logic for dropped txs.
Updated 14 days ago