How to estimate gas in Arbitrum
Head over to the Stylus gas docs for Stylus-specific guidance.
This how-to is intended for users and developers interested in understanding how gas operates in Arbitrum, how it's calculated, and how to estimate it before submitting transactions. More detailed information about these calculations can be found in this Medium article and the Gas and Fees page.
Skip the formula, focus on practical know-how
Before diving into the specifics and the formula, if you're looking for a practical way to estimate gas for your transaction, you can rely on the standard gas estimation process. This can be achieved by calling an Arbitrum node's eth_estimateGas, which provides a value (gas limit) that should sufficiently cover the entire transaction fee at the specified child chain gas price.
Multiplying the value obtained from eth_estimateGas by the child chain gas price will give you the total amount of Ether required for the transaction to be successful. It's important to note that, for a specific operation, the result of eth_estimateGas value may vary over time due to fluctuations in the parent chain calldata price, see below to learn why!
Alternatively, to obtain the gas limit for your transaction, you can call NodeInterface.gasEstimateComponents() and then use the first result, which is gasEstimate. Next, to find the total cost, you need to multiply this amount by the child chain gas price, which is available in the third result, baseFee.
Note that when working with parent to child chain messages (also known as retryable tickets), you can use the function L1ToL2MessageGasEstimator.estimateAll() of the Arbitrum SDK or NodeInterface.estimateRetryableTicket() to get all the gas information needed to send a successful transaction.
Breaking down the formula
We'll now break down the formula mentioned in the Medium article, moving then to where to get the information of each variable, and finally seeing an example of how to apply the formula in your code as well as other practical ways of estimating gas costs.
However, if you want to jump straight to the code, we have created this script in our tutorials repository that goes through all the calculations explained in this how-to.
As explained in the Medium article, the transaction fees to pay at any given moment are the result of the following product:
Transaction fees (TXFEES) = L2 Gas Price (P) * Gas Limit (G)
This Gas Limit includes the gas of the child chain computation and an additional buffer to cover the parent chain gas to be paid by the Sequencer when posting the batch including this transaction on the parent chain.
Gas Limit (G) = Gas used on L2 (L2G) + Extra Buffer for L1 cost (B)
This buffer takes into account the cost of posting the transaction, batched and compressed, on the parent chain. The parent chain estimated posting cost is calculated by multiplying these two values:
- L1S, which estimates the amount of data the transaction will take up in the batch by compressing the transaction with Brotli.
- L1P, which is the L2's estimated view of the current parent chain's price of data (per byte), which the child chain dynamically adjusts over time.
More information is available in this page.
L1 Estimated Cost (L1C) = L1 price per byte of data (L1P) * Size of data to be posted in bytes (L1S)
To calculate the buffer, that estimated cost is divided by the child chain Gas Price.
Extra Buffer (B) = L1 Estimated Cost (L1C) / L2 Gas Price (P)
Finally, using all of the above elements, the formula can be written as follows:
TXFEES = P * (L2G + ((L1P * L1S) / P))