EIP-1559 Gas Costs: Separate the Estimate, Fee Cap and Receipt
TECH INSIGHT / EXPLAINED
Separate three quantities: the gas limit you authorize, the gas actually used, and the effective price paid per unit. A fee cap is a budget ceiling, not the final bill.
The formula, including a clipped tip
For an eligible EIP-1559 transaction, effective price = base fee + min(priority-fee cap, fee cap − base fee). If the fee cap is below the block’s base fee, it cannot be included under those parameters. Raising a tip does not guarantee ordering. This explanation concerns Ethereum execution gas; another chain or an L2 may have additional fee rules.
def effective_gas_price(base, tip_cap, fee_cap):
if min(base, tip_cap, fee_cap) < 0 or fee_cap < tip_cap:
raise ValueError('invalid fee parameters')
if fee_cap < base:
raise ValueError('fee cap below this block base fee')
return base + min(tip_cap, fee_cap - base)
assert effective_gas_price(30, 3, 32) == 32 # units: gwei
assert 150_000 * 32 * 10**9 == 4_800_000_000_000_000A receipt versus a budget
With a 30 gwei base fee, a 3 gwei tip cap and a 32 gwei total cap, the actual tip can be only 2 gwei. If execution uses 150,000 gas, the execution charge is 0.0048 ETH. A 180,000 gas limit does not mean all 180,000 units are charged.
For a conservative authorized ceiling, 180,000 × 32 gwei is 0.00576 ETH. Compare this ceiling and an expected estimate separately against the potential return; convert both into the same token using a documented price snapshot.
What estimation can and cannot establish
Estimate against the intended sender, value, calldata and relevant state. Handle RPC failures separately from simulated contract reverts. Neither an estimate nor a fixed 20% buffer guarantees success after the state changes.
A production transaction also needs the correct chain ID, nonce, value and signature. Check every header and tip lookup error; a missing BaseFee cannot safely be dereferenced. Treat a shortened code fragment as an illustration until those required fields are supplied.
An operational decision record
Keep the block used for estimation, estimated gas, gas limit, both fee caps, quote expiry and receipt fields. A reverted included transaction can still cost gas, so compare failed-attempt spending with successful-trade spending. A “2 × base fee + tip” heuristic buys headroom but is neither a protocol requirement nor a promise of inclusion.
Translate fee headroom into waiting blocks
Consider a synthetic sequence starting at 30 gwei, with every block consuming twice its gas target. Applying the EIP-1559 integer update gives 60.818595885 gwei after six increases and 68.420920370 gwei after seven. With a 3 gwei priority-fee cap and a 63 gwei total cap, the sixth step clips the tip to 2.181404115 gwei. At the seventh step the total cap is insufficient.
base = 30_000_000_000 # wei per gas
for _ in range(7):
base += max(base // 8, 1)
print(base)
# step 6: 60818595885
# step 7: 68420920370
This independent Python reproduction demonstrates a conditional boundary, not a congestion forecast. Other blocks require the actual parent gas usage and target. Integer flooring and the minimum increase of 1 wei mean that repeatedly multiplying a floating-point value by 1.125 is not equivalent for every input. The update rule comes from EIP-1559.
Prevent pending transactions from sharing one budget
Checking the balance for one transaction is insufficient. Suppose the gas limit is 180,000, the total cap is 63 gwei, and the attached value is 0.01 ETH. A conservative reservation for that transaction is 0.02134 ETH. Preparing two transactions with distinct nonces requires reserving 0.04268 ETH to avoid allocating the same balance twice.
This reservation is an application funding policy, not the final bill. Replacement candidates with the same sender and nonce are alternatives: only one can execute on a single canonical chain. A ledger can reserve the largest requirement per nonce group instead of summing every candidate. However, submitting a replacement does not prove the earlier candidate was canceled. Reconcile canonical receipts and the account nonce before releasing reservations.
Do not bill cumulative gas as individual gas
In a synthetic block, suppose earlier transactions consumed 21,000 gas and the cumulative count reaches 171,000 after the current transaction. The current transaction used 150,000 gas. Multiplying cumulativeGasUsed by its price incorrectly includes work from other transactions. Reconcile execution charges using gasUsed and effectiveGasPrice; their meanings are specified in the JSON-RPC receipt documentation.
Preserve the chain, transaction hash, and inclusion block hash in the cost ledger. If a reorganization removes a receipt, return its record to a provisional state instead of retaining settled spending or adding a replacement receipt twice. An absent receipt does not immediately establish failure. Distinguish pending execution, an observation failure, and possible reorganization in the query state.
Make the gas policy expire with the plan
An execution plan needs both a fee-refresh condition and a stop condition. For example, a clipped tip should not automatically trigger unlimited increases to the total cap. Discard a plan when its updated cost exceeds the application's budget. Record a fee-only retry separately from a new candidate with changed calldata so later diagnosis can identify what actually changed.
Use the cost categories in the Ethereum gas documentation when designing the ledger. These examples cover ordinary execution gas only. Account for L2 data charges or blob charges separately instead of hiding them inside one execution-cost field. The numbers are illustrative, not recommended fee settings or a recommendation to submit a transaction.
Sources and further reading
Content and examples reviewed: 2026-10-01
댓글
댓글 쓰기