Glossary

Gas Estimation

Gas estimation predicts how much computational gas a transaction will consume, helping users set appropriate gas limits to avoid failures.

Key Takeaways

  • Gas estimation predicts how much computational work a transaction requires: Ethereum nodes simulate the transaction against current state using the eth_estimateGas RPC call and return the gas consumed, helping users set an appropriate gas limit.
  • Estimates can be inaccurate because blockchain state changes between estimation and execution: other transactions, MEV activity, and non-deterministic contract behavior can all shift the actual gas consumed, making the original estimate too low or too high.
  • Gas estimation differs from fee estimation: gas estimation determines how much gas a transaction needs, while fee estimation under EIP-1559 determines the price per unit of gas (base fee plus priority tip). Both are needed to calculate total transaction cost.

What Is Gas Estimation?

Gas estimation is the process of predicting how much computational gas an Ethereum transaction will consume before it is submitted to the network. Every operation on the Ethereum Virtual Machine (EVM) costs a fixed amount of gas: a simple transfer costs 21,000 gas, while complex smart contract interactions can require hundreds of thousands or even millions. Setting the right gas limit is critical because a limit that is too low causes the transaction to revert (and the gas is still consumed), while a limit that is too high reserves capacity the sender does not need.

The standard way to estimate gas is through the eth_estimateGas JSON-RPC method, which every Ethereum node exposes. Wallets like MetaMask, libraries like ethers.js and viem, and infrastructure providers like Infura all rely on this call behind the scenes to suggest gas limits for users. Despite its ubiquity, gas estimation is inherently imperfect: the estimate is a snapshot of what would happen if the transaction executed right now, but by the time it is included in a block, the state may have changed.

How It Works

When a client calls eth_estimateGas, the node performs the following steps:

  1. Accepts a transaction object containing fields like from, to, value, and data (the calldata for contract interactions)
  2. Simulates the transaction against the current blockchain state without broadcasting it to the network or modifying the chain
  3. Returns a hex-encoded gas value representing the estimated gas required for the transaction to complete successfully

The result is not simply the gas used during simulation. Clients like Geth run a binary search to find the smallest gas budget that allows the transaction to execute without reverting. The search starts by dry-running the transaction at the maximum allowed limit (typically the pending block's gas limit), then narrows the range between the gas actually consumed and that upper bound.

The Binary Search Algorithm

Geth's estimation algorithm assumes monotonicity: if a transaction succeeds with a gas limit of N, it should succeed with any limit greater than N. The binary search exploits this by halving the range on each iteration:

// Simplified pseudocode of Geth's gas estimation
function estimateGas(tx):
  lo = gasUsed(tx)        // lower bound from initial execution
  hi = blockGasLimit      // upper bound from pending block
  cap = hi

  while lo + 1 < hi:
    mid = (lo + hi) / 2
    result = simulate(tx, gasLimit = mid)
    if result.success:
      hi = mid            // succeeded: try lower
    else:
      lo = mid            // failed: need more gas

  return hi               // smallest gas limit that succeeds

This approach typically converges in 10 to 20 iterations. For simple ETH transfers, some clients (like Reth) skip the search entirely and return the known constant of 21,000 gas.

Gas Cap and Upper Bounds

Nodes enforce a cap on eth_estimateGas to prevent abuse. Geth's default RPC gas cap is set to 50 million gas (configurable via the --rpc.gascap flag). If no gas limit is specified in the transaction object, the node uses the pending block's gas limit as the upper bound. The Ethereum mainnet block gas limit is currently around 36 million gas, which means a single transaction cannot consume more than that.

Why Estimates Can Be Wrong

Gas estimation simulates against a snapshot of state, but real execution happens in a future block with potentially different state. Research measuring EVM workloads found that gas estimates vary across nearby historical states for approximately 14% of transactions on Ethereum mainnet and as high as 46% on Layer 2 chains like Base. Several factors drive this inaccuracy:

State Changes Between Estimation and Execution

Every transaction in a block modifies the blockchain state. Between the moment you call eth_estimateGas and when your transaction is actually included in a block, other transactions may alter the contract storage your transaction depends on. A DeFi swap that looked like it would cost 150,000 gas might cost 180,000 gas if a prior transaction in the same block changes the liquidity pool's state.

MEV and Transaction Ordering

MEV searchers can insert transactions before yours, altering the state your transaction sees. In a sandwich attack, a bot front-runs your swap to move the price, making your transaction consume different gas than estimated. MEV and DeFi transactions account for the largest share of estimation variance because their gas consumption is highly state-dependent.

Non-Monotonic Gas Behavior

The binary search assumes that if a transaction succeeds at gas limit N, it will succeed at N+1. This is not always true. Some contracts have branching logic where different gas limits trigger different code paths. There can be separate regions of gas limits that make a transaction successful, with gaps in between where it fails. This edge case is rare but can produce incorrect estimates.

Storage Refunds and Dynamic Costs

Ethereum refunds a portion of gas when storage is cleared (e.g., setting a storage slot from a non-zero value to zero). These refunds depend on the exact pre-execution state. If the storage slot was already zero when estimated but non-zero at execution time (or vice versa), the actual gas consumed will differ from the estimate.

Gas Estimation vs. Fee Estimation

These are two separate problems that are often confused. Gas estimation answers the question: how many units of gas will this transaction consume? Fee estimation answers: what price per gas unit should I pay to get included in a block?

AspectGas EstimationFee Estimation
QuestionHow much gas will this use?What price per gas to pay?
RPC methodeth_estimateGaseth_gasPrice, eth_feeHistory, eth_maxPriorityFeePerGas
UnitGas (dimensionless)Wei per gas (gwei)
Changed by EIP-1559?NoYes: split into base fee + priority fee
DeterminesGas limit to setmaxFeePerGas and maxPriorityFeePerGas

Under EIP-1559, the base fee is set algorithmically by the protocol and adjusts based on block fullness. Users add a priority fee (tip) to incentivize block builders. The total transaction cost is: gas used multiplied by the effective gas price (base fee plus priority fee). Gas estimation determines the first factor; fee estimation determines the second. For a deeper look at how paymasters can abstract these costs away from end users, see the research on gasless paymaster transaction design.

Gas Limit Setting Strategies

Choosing the right gas limit involves balancing two risks: setting it too low causes the transaction to fail, while setting it too high can waste fees in certain edge cases.

Too Low: Transaction Reverts

If the gas limit is below what the transaction actually needs, the EVM runs out of gas mid-execution and the transaction reverts. The critical consequence: the sender still pays for all the gas consumed up to the point of failure. The intended state changes are rolled back, but the gas fee is not refunded. This makes underestimation expensive.

Too High: Wasted Capacity

On a successful transaction, unused gas is refunded to the sender, so setting a high limit does not directly waste money. However, there are indirect costs: the gas limit counts against the block's total gas budget during transaction inclusion, and some gas price mechanisms on L2 networks may factor the gas limit into pricing. Additionally, if the transaction reverts for a reason unrelated to gas (such as a contract revert condition), the entire gas limit is consumed.

Common Strategies

  • Safety margin: multiply the eth_estimateGas result by 1.2 to 1.5 to account for state changes. Most wallets apply a margin automatically.
  • Fixed limits for known operations: simple ETH transfers always cost 21,000 gas. ERC-20 transfers to a previously funded address are consistently around 65,000 gas. Hardcoding limits for predictable operations avoids the estimation call entirely.
  • Simulation with state overrides: advanced users can pass state overrides to eth_estimateGas or eth_call to simulate against a modified state, testing how the estimate changes under different conditions.
  • Gas sponsorship through paymasters: in account abstraction workflows, a paymaster contract handles gas payment on behalf of the user, absorbing estimation risk and simplifying the user experience.

Use Cases

Wallet Gas Suggestions

Every Ethereum wallet calls eth_estimateGas before prompting the user to confirm a transaction. The estimate populates the gas limit field and, combined with fee estimation, shows the user the expected total cost. Without this step, users would need to manually research gas costs for every contract interaction.

DApp Transaction Builders

Decentralized applications use gas estimation to build transactions programmatically. A DEX aggregator, for example, estimates gas for each possible swap route and factors the gas cost into its routing decision, selecting the path that minimizes total cost (swap slippage plus gas).

Gas Optimization Tooling

Smart contract developers use gas estimation during development to benchmark their contracts. By calling eth_estimateGas against a local node or fork, developers can measure how changes to contract logic affect gas consumption and identify optimization opportunities before deploying to mainnet.

Batch Transaction Planning

Protocols that batch multiple operations into a single transaction (common in L2 sequencers and batch settlement systems) use gas estimation to determine whether a batch fits within the block gas limit and to price the batch appropriately for users.

Practical Example

Here is how gas estimation looks using ethers.js to prepare an ERC-20 token transfer:

// Estimate gas for an ERC-20 transfer
const contract = new ethers.Contract(tokenAddress, erc20Abi, provider);

const gasEstimate = await contract.transfer.estimateGas(
  recipientAddress,
  ethers.parseUnits("100", 18)
);

// Apply a 20% safety margin
const gasLimit = (gasEstimate * 120n) / 100n;

// Get current fee data (EIP-1559)
const feeData = await provider.getFeeData();

// Send with the estimated gas limit and fee parameters
const tx = await contract.transfer(
  recipientAddress,
  ethers.parseUnits("100", 18),
  {
    gasLimit,
    maxFeePerGas: feeData.maxFeePerGas,
    maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
  }
);

Notice the two separate estimation steps: estimateGas for the gas quantity and getFeeData for the gas price. Both are needed to construct a complete transaction.

Why It Matters

Accurate gas estimation directly impacts user experience and cost. An underestimate causes a failed transaction where the user loses the gas fee with nothing to show for it. An overestimate, while less harmful, can confuse users who see inflated cost previews and may hesitate to transact. For protocols built on Ethereum and EVM-compatible chains, gas estimation is a fundamental piece of infrastructure that runs behind every wallet interaction.

The complexity of gas estimation is one reason why many modern wallet designs pursue gasless transactions and gas sponsorship models. By abstracting gas away from end users entirely, platforms like Spark eliminate the estimation problem at the user-facing layer. On Bitcoin Layer 2 networks like Spark, the UTXO-based model avoids the concept of gas altogether, offering predictable transaction costs without the estimation uncertainty inherent to the EVM.

Risks and Considerations

Failed Transactions Still Cost Money

The most consequential risk of bad gas estimation is that failed transactions are not free. When a transaction runs out of gas, the sender's intended state changes are reverted, but the gas consumed up to the failure point is permanently spent. For expensive contract calls, this can mean losing significant fees on a transaction that accomplished nothing.

Estimation Calls Have Latency

Each eth_estimateGas call requires the node to simulate the full transaction execution. For complex contract interactions, this can take hundreds of milliseconds. Applications that need to estimate gas for multiple possible transaction paths (like DEX aggregators comparing routes) may face noticeable latency from sequential estimation calls.

State Staleness

By the time a transaction is included in a block, the estimate may be several blocks old. During periods of high network congestion or intense MEV activity, state can change significantly between estimation and inclusion. Applications that handle large values or interact with highly contested contracts should use larger safety margins or implement retry logic with re-estimation.

Cross-Client Differences

Different Ethereum clients (Geth, Reth, Nethermind, Besu) may return slightly different estimates for the same transaction. While they all implement the same EVM specification, their estimation algorithms, heuristics, and rounding behavior can vary. Applications that need consistent estimates should be aware of which client their RPC provider runs.

This glossary entry is for informational purposes only and does not constitute financial or investment advice. Always do your own research before using any protocol or technology.