How to minimize fees on Ethereum transactions


How to minimize fees on Ethereum transactions
15.03.2023 12:37
Post earned 0.00 UFO

We will talk about the transfers of ERC-20 tokens, such as USDT, DAE or DYDX.

The first thing you must do is fill up your wallet with ETH coins. Never keep your balance close to only for paying fees - it's fraught with the risk that one day you'll get a transaction that hangs for a long time, or the famous "out of gas" error, in which the tokens won't transfer but fee burns.

Fees are paid in units of gas. A normal ETH transfer requires 21'000 units of gas - that number is always the same. But any interaction with a contract, while token transfer is exactly the interaction with a smart contract, requires much more units. And this number is not constant, for example USDT transfer requires from ~35'000 to ~75'000, DYDX transfer - from ~200'000 to ~250'000.

The good news is that any wallet determines needed amount of gas units at the moment - this parameter in wallets is called gasLimit - and adds more just in case, for example, if the transaction will take a long time to confirm and the required number of units will increase. So never decrease gasLimit offered by wallet, and I'd even recommend increasing it, because some wallets may not determine it correctly. For example, if you are creating a USDT transaction and the wallet offers you a limit of 40'000, it makes sense to increase it to 80'000 just in case. You can always look at how much gas a transfer of your token usually spend in and be guided by these numbers. In any token transaction with Transfer method, look in More Details for the Gas Limit & Usage by Txn parameter, but remember that this value is not constant. The main thing is that the gas limit you set has no effect on the final fee, the transaction will burn exactly as much ether as it needs at the time the validator confirms the transaction. That is, the final fee will be known only when the transaction is confirmed in the blockchain. Unfortunately, this is how EVM works, it is impossible to predict the exact fee before sending.

The priority of the transaction is set by two parameters - maxFeePerGas and maxPriorityFeePerGas, and does not depend on the transaction amount.

maxFeePerGas - the maximum gas price the transaction can use.

maxPriorityFeePerGas - this is the fee that is not burned, and goes directly to the validator who confirmed the transaction, usually it is 1-2 Gwei - I recommend not to change it.

Unfortunately, not all wallets support type 2 transactions, and they still use type 0, which has one parameter gasPrice. The fundamental difference here is that if you set gasPrice, for example, 50 Gwei, the fee on confirmation will be 50 * (gas units), but if you use two parameters, it will be equal to (base fee + maxPriorityFeePerGas) * (gas units).

Base fee is calculated in the Ethereum blockchain and depends solely on the network load, but with the maxFeePerGas parameter we only set the maximum gas price value at which the transaction will be confirmed. If the base fee in the network is higher at the moment, the transaction will be confirmed only when the base gas price drops to the level we set minus maxPriorityFeePerGas. Well, quite simply, with the maxFeePerGas parameter we are saying that we are ready to spend no more than 25 Gwei per unit of gas for the transaction. Since Ethereum fees can go up and down very quickly, this allows us not to try to predict the price of gas, like with old gasPrice option, and as a result, not to overpay.

Example: I transfer USDT. I go to the gas tracker, see the current Base fee and Priority fee. So, our inputs are: Base Fee - 30 Gwei, Priority Fee - 2 Gwei. I want to save money by just waiting for the base gas price to drop. "What if it hangs for a few days?", you ask. I don't see any problem with this option, because the transaction can always be replaced with a larger maxPriorityFeePerGas, maxFeePerGas and the same nonce parameter. In the transaction parameters I put maxPriorityFeePerGas = 2, maxFeePerGas = 25, gasLimit = 100'000. In case the base fee drops to 23 Gwei, my transaction is validated and I pay (23+2)*(gas units) for it. For example, the transaction spent 45000 units, the total fee was 25*45000 = 1125000 Gwei.

What is Gwei? 1 Gwei = 0.000000001 ETH. There is a simple calculator at The transaction fee was 0.001125 ETH. But if the base fee had drop to 20 Gwei, which may well happen while you're signing the transaction in your wallet for a couple of minutes, and the transaction was confirmed at this price and burned the same amount of gas units, the transaction would have cost (20+2)*45000 Gwei = 0.00099 ETH. It's not much economy, but it's nice. Now imagine that I send a token that needs a lot more gas units, for example DYDX - saving a 2-3 Gwei would end up saving about $1 at the moment.

So, a quick summary, given the current realities, and a couple of tips:

1) Keep ETH on your wallet for fees at least for $10-20

2) Use wallets that allow you to control maxFeePerGas, maxPriorityFeePerGas and nonce parameters. Nonce is used to replace the transaction in case of "hang", about that below. A good wallet is Metamask, it can be used also with Trezor/Ledger, and it supports any EVM blockchain

3) Never decrease gasLimit, on the contrary increase, estimate the last transactions of the token you need by

4) Use to know the current network fees

5) Never send the next transaction before confirming the previous one (Success or Fail status in etherscan)

6) When transferring ETH, pay attention to the address of the recipient. Some exchanges use smart contracts to accept deposits, which means the transaction needs more than 21'000 of gas units - in my experience up to 50'000. Before sending, find the address issued by the exchange in etherscan and see what it says next to the address: Address or Contract

7) If you are not in a hurry, then send transactions in the 04-07 AM by UTC - often the gas price at this time is the lowest

How to replace Pending transaction.

The first thing you must understand is that there is no such thing as a transaction "cancellation" - it is always the sending of a competing transaction with the same nonce parameter. A cancellation means sending 0 ETH to yourself with the same nonce and higher maxFeePerGas and maxPriorityFeePerGas, but technically it is exactly the same competing transaction as in a "replacement" transaction.

It is also worth understanding that even if your hanging transaction disappeared from etherscan or it even gives status "dropped" for transaction - this does not mean that the transaction is cancelled. It can easily "resurrect" - this is due to the fact that each node has its own transaction mempool, there is no centralized database where "hang" transactions are stored and discarded from. What etherscan displays is only what the nodes of that particular service know. In practice, a transaction can sends between nodes for years and, as a consequence, appear and disappear in explorers.

So, the transaction pending for a long time.

1) Go to explorer and find your wallet address. In the list of transactions, find the last successful transaction marked OUT or SELF, in the transaction details find its nonce, let's say nonce = 25 - so the nonce for the next (currently pending) transaction should be greater by one - 26.

2) Configure Metamask wallet.

Settings >> Advanced >> Turn on "Advanced gas controls" and "Customize transaction nonce"

3) Click "Send"

4) Enter recipient address and amount as in Pending transaction. You can also create a transaction with any amount, recipient and token, including you can enter your own address and send 0 ETH - so you can "cancel" the transaction.

5) In the next window set the required Сustom Nonce, then Market >> Advanced >> Set higher values of "Max base fee" (maxFeePerGas) and "Priority Fee" (maxPriorityFeePerGas). The Priority Fee can be increased quite a bit, for example in the pending transaction you had 1 Gwei, you can put 1.1, but set Max base fee more relevant to the current fees in the Ethereum network

It is also not uncommon for a user to create an entire queue of transactions by sending new ones with the following nonce value. Transactions are executed sequentially, that is, until the Pending transaction with nonce=26 is executed, the Pending transaction with nonce=27 will not be executed. This can lead to a very unpleasant situation. Example:

1) The user has 0.15 ETH in his account and sends a 0.1 ETH transaction with a low maxFeePerGas (or gasPrice for the old transaction type), it is not confirmed for a long time

2) The user sends a second transaction with the following nonce value and the same amount

3) The base fee in the network drops and transaction number 1 is executed. For the user, it looks normal in the wallet - the required amount is gone, all is well

4) BUT. Transaction number 2 will remain unconfirmed, because there is only 0.05 ETH in user account.

5) In the future, when wallet receives 0.06 ETH, then the transaction of 0.1 ETH goes out without user confirmation - in fact there was pending transaction and it executed when the needed sum appeared on user's account.

So, always keep an eye on your wallet via etherscan, there will always be more comprehensive information, and don't send the next transaction until you've dealt with the previous one.

One last tip - I highly recommend you to experiment with replacing transactions in Goerli testnet first, you can get test coins here (registration required).

Any questions? Welcome to my chat:

Post earned 0.00 UFO

Post earned 0.00 UFO