Ethereum

Ethereum

Gas Management

Gas is where Ethereum's economics meet your application's reliability. Every block has a gas limit, every transaction pays in ETH for the computation it triggers, and since EIP-1559 the base price floor moves with demand on each new block. Get the fee wrong on the low side and your transaction sits stuck while the base fee rises past it; overpay and you've burned user funds for no benefit. Reading gas at the block level — the limit, the target, the current baseFeePerGas — is how you set fees that actually land.

Done well, gas management means transactions that confirm in the slot you expect at a price your users accept. That's the difference between a checkout that completes and one that hangs. This guide covers the block-level mechanics on chain 1: the gas limit and target, how EIP-1559's base fee and priority tip combine, and the estimation strategies that keep type-2 transactions both cheap and reliably included.

Gas Fundamentals

  • The block gas limit caps total work. Each Ethereum block can hold roughly 30 million gas of execution (validators nudge the limit up or down within protocol bounds). Your transaction's gas usage has to fit inside what's left after others claim space, and the limit is the hard ceiling on how much can be packed into a single 12-second slot.
  • Price moves with demand around a target. EIP-1559 sets a per-block gas target at half the limit (around 15 million). When blocks run above target the base fee rises for the next block; below target it falls. That feedback loop is what drives the fee swings you see during a popular NFT mint or a market crash deleveraging on Aave.
  • Base fee plus priority tip. A type-2 transaction sets maxFeePerGas (the most you'll pay per gas) and maxPriorityFeePerGas (the tip to the validator). You pay the block's current baseFeePerGas — which is burned, removing ETH from supply — plus your tip, never more than your max. Read baseFeePerGas off the latest block and eth_maxPriorityFeePerGas for a sane tip; eth_feeHistory gives you the recent distribution to set both intelligently.
  • Estimation, with trade-offs. eth_estimateGas tells you the gas units a call will consume, but it can under-report for paths whose cost depends on state, so pad it. For the price, a conservative maxFeePerGas (well above the current base fee) buys inclusion through fee spikes at the risk of overpaying; a tight one saves ETH but risks getting stranded when the base fee climbs. The legacy eth_gasPrice collapses both into one number and is best avoided for new code.

Implementation Strategies

// Get block gas limit
const getBlockGasLimit = async () => {
const block = await web3.eth.getBlock('latest');
return block.gasLimit;
};
// Estimate optimal gas price
const getOptimalGasPrice = async () => {
const blockCount = 10;
const latest = await web3.eth.getBlockNumber();
const blocks = await Promise.all(
[...Array(blockCount)].map((_, i) => web3.eth.getBlock(latest - i))
);
const gasPrices = blocks.map((block) => block.baseFeePerGas);
return Math.floor(gasPrices.reduce((a, b) => a + b) / blockCount);
};

Optimization Techniques

  • Adjust fees dynamically. Don't hardcode a gas price. Pull baseFeePerGas from the latest block and a tip from eth_maxPriorityFeePerGas right before signing, then set maxFeePerGas to roughly twice the base fee plus the tip so you stay included even if the next few blocks run hot. Re-quote on every transaction, since the base fee can shift meaningfully within a couple of slots.
  • Batch to amortize fixed cost. Every transaction pays the 21,000-gas base cost just to exist. Bundling several actions into one contract call — a multicall, a single batched transfer — pays that overhead once instead of per action, which is a real saving when you're doing many small operations.
  • Run non-urgent work off-peak. "Off-peak" on Ethereum isn't a time of day so much as a moment of low blockspace demand, often weekends or quieter UTC hours, when blocks sit below the gas target and the base fee drifts down. Schedule batch settlements, rebalances, or claim sweeps for those windows and watch eth_feeHistory to time them.
  • Set the gas limit from a padded estimate. Use eth_estimateGas for the units, then add headroom (commonly 10 to 25%) so a slightly more expensive execution path doesn't run out of gas and revert. Don't pad blindly to the block limit, though — an over-large limit can raise the cost of some operations and wastes nothing only if execution stays cheap.
  • Match the fee strategy to the use case. A liquidation bot or an arbitrage transaction that must land in the next block wants an aggressive maxFeePerGas and a generous tip — being outbid costs more than overpaying. A routine user transfer or a background batch wants a conservative max close to the current base fee, accepting that it may wait a few blocks to save ETH.

See also

Ready to call this in production?

Free tier covers personal projects. Pay-as-you-go scales without a card.