Why eth_estimateGas is higher than gas used
Last updated:
At a glance
| Property | Value |
|---|---|
| What eth_estimateGas returns | Gas needed to complete; may be significantly more than gas used |
| 63/64 rule (EIP-150) | A subcall gets at most all but one 64th of the remaining gas |
| Refund cap (EIP-3529) | gas_used // 5 |
| Without a gas limit (geth) | The pending block's gas limit is the upper bound |
What you see
The receipt's gasUsed is noticeably lower than the eth_estimateGas result you used as the gas limit. Or the opposite: a transaction sent with a limit equal to a previous gasUsed runs out of gas.
Why this happens
Ethereum's JSON-RPC documentation says eth_estimateGas "will not be added to the blockchain" and that "the estimate may be significantly more than the amount of gas actually used by the transaction, for a variety of reasons including EVM mechanics and node performance". One mechanism is EIP-150's "all but one 64th" rule: a call can pass at most 63/64 of the remaining gas to a subcall, so a transaction with nested calls needs a higher limit than the gas it ends up consuming. Another is refunds: under EIP-3529 clearing storage earns a refund of up to gas_used // 5 at the end of the transaction, which lowers the charged gasUsed but not the gas the transaction needs while it runs. Finally, the estimate is computed against the state at the time of the call; if that state changes before inclusion, so does the gas. When no gas limit is given, the documentation notes that geth uses the pending block's gas limit as an upper bound.
What to do
- Use the estimate as the gas limit (optionally with a margin), not a previous transaction's gasUsed.
- Expect gasUsed to be lower for transactions that clear storage or make nested calls; that difference is not overpayment of the unused limit.
- Re-estimate right before sending when the transaction depends on state that changes often.
- Pass the same from, value and block as the real transaction when estimating, so the simulation takes the same code path.
When this is not our problem
The gap between estimate and gasUsed comes from EVM gas rules defined in EIPs, the same on every node, whoever operates it, Triport included. The estimate is a simulation; only the gas limit you choose is up to you.
FAQ
- Why is gasUsed lower than eth_estimateGas?
- The estimate is the gas needed to succeed. Refunds (capped at gas_used // 5) and the 63/64 reserve for subcalls mean a transaction can need more gas than it is finally charged.
- Can I use last time's gasUsed as the gas limit?
- Not safely. A transaction can need more gas during execution than it is charged afterwards, so a limit equal to gasUsed can run out of gas.