# How is the "Base Fee Per Gas" computed for a new block?

There are numerous articles describing that after EIP1559 the blocks `baseFeePerGas` is based on the previous blocks `baseFeePerGas`, `gasUsed` and `gasLimit` and that it can change by a maximum of ±12.5% from block to block.

But what is the exact formula to compute the next blocks `baseFeePerGas`? E.g.: How is the `baseFeePerGas` of block 13031168 computed?

``````Block 13031167:
Gas Used: 23798810 (79.10%) +58% Gas Target
Gas Limit: 30087944
Base Fee Per Gas: 47.209136185 Gwei

Block 13031168:
Gas Used: 892841 (2.96%) -94% Gas Target
Gas Limit: 30117325
Base Fee Per Gas: 50.643305194 Gwei
``````

you can find the exact formula in the EIP 1559 specs:

https://eips.ethereum.org/EIPS/eip-1559

``````    # check if the base fee is correct
if INITIAL_FORK_BLOCK_NUMBER == block.number:
expected_base_fee_per_gas = INITIAL_BASE_FEE
elif parent_gas_used == parent_gas_target:
expected_base_fee_per_gas = parent_base_fee_per_gas
elif parent_gas_used > parent_gas_target:
gas_used_delta = parent_gas_used - parent_gas_target
base_fee_per_gas_delta = max(parent_base_fee_per_gas * gas_used_delta // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR, 1)
expected_base_fee_per_gas = parent_base_fee_per_gas + base_fee_per_gas_delta
else:
gas_used_delta = parent_gas_target - parent_gas_used
base_fee_per_gas_delta = parent_base_fee_per_gas * gas_used_delta // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR
expected_base_fee_per_gas = parent_base_fee_per_gas - base_fee_per_gas_delta
assert expected_base_fee_per_gas == block.base_fee_per_gas, 'invalid block: base fee not correct'
``````

Or in the official sources:

``````// CalcBaseFee calculates the basefee of the header.
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
if !config.IsLondon(parent.Number) {
return new(big.Int).SetUint64(params.InitialBaseFee)
}

var (
parentGasTarget          = parent.GasLimit / params.ElasticityMultiplier
parentGasTargetBig       = new(big.Int).SetUint64(parentGasTarget)
baseFeeChangeDenominator = new(big.Int).SetUint64(params.BaseFeeChangeDenominator)
)
// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
if parent.GasUsed == parentGasTarget {
return new(big.Int).Set(parent.BaseFee)
}
if parent.GasUsed > parentGasTarget {
// If the parent block used more gas than its target, the baseFee should increase.
gasUsedDelta := new(big.Int).SetUint64(parent.GasUsed - parentGasTarget)
x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta)
y := x.Div(x, parentGasTargetBig)
baseFeeDelta := math.BigMax(
x.Div(y, baseFeeChangeDenominator),
common.Big1,
)

} else {
// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
gasUsedDelta := new(big.Int).SetUint64(parentGasTarget - parent.GasUsed)
x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta)
y := x.Div(x, parentGasTargetBig)
baseFeeDelta := x.Div(y, baseFeeChangeDenominator)

return math.BigMax(
x.Sub(parent.BaseFee, baseFeeDelta),
common.Big0,
)
}
}
``````

https://github.com/ethereum/go-ethereum/blob/0a68558e7e025afebf67b81bf48ecb8b0fa7c06d/consensus/misc/eip1559.go#L54