Gas Fees in gno.land
Every transaction carries two flags:
--gas-wanted: the most gas it may use.--gas-fee: one flat amount it pays in full.
Get both by running your command with -simulate only first, as
Gas Estimation shows. If a transaction was rejected, start at
Common Errors.
What is Gas?
Gas measures the computational and storage work a transaction performs. Every operation has a fixed cost, so the same transaction against the same state uses the same gas every time. Demand moves the price of that gas, never the amount.
Charging for work keeps spam off the network. Every fee goes to one address,
the chain's auth:p:fee_collector parameter.
Gas Parameters
When submitting transactions to gno.land, you need to specify two gas-related parameters:
Gas Wanted
--gas-wanted specifies the maximum amount of gas your transaction is allowed
to consume. If your transaction requires more gas than this limit, it fails
with an "out of gas" error and its effects are rolled back.
Gas Fee
--gas-fee is the whole fee for the transaction, one flat amount. It is
expressed in ugnot (micro-GNOT), so 1000000ugnot is one GNOT.
--gas-wanted turns that fee into a rate, and the rate is what the network
checks:
Gas Price = Gas Fee ÷ Gas Wanted
By default (-simulate test), gnokey simulates the transaction first and does
not send it if the simulation fails, so it costs nothing. -simulate skip sends
it without that check. Once a transaction is in a block you pay the whole fee,
whether it used less gas than it asked for or failed outright, and one that
passed simulation can still fail there if the state changed in between.
The easiest way to size both is -simulate only, which
queries the current gas price and prints the recommended fee.
Gas Price
The network dynamically adjusts the minimum required gas price after each block based on demand. This ensures the network responds to congestion by increasing prices when usage is high and decreasing them when usage is low.
The Gas Price is a Rate
The gas price is returned as a GasPrice object with two fields:
gas- the gas units (e.g., 1000)price- the price for those gas units (e.g., "1ugnot")
Together, these represent a rate. {gas: 1000, price: "1ugnot"} means 1
ugnot per 1000 gas units, which simplifies to 0.001 ugnot per gas unit. That is
the floor the price never drops below. Under load the price field grows.
To calculate the minimum fee manually:
- Query the current gas price
- Calculate the rate:
price / gas - Multiply by your
--gas-wanted
Example:
# Query returns: {gas: 1000, price: "1ugnot"}
# Rate = 1 ÷ 1000 = 0.001 ugnot/gas
# If you want --gas-wanted 2000000:
# Minimum fee = 2,000,000 × 0.001 = 2,000 ugnot
# So set: --gas-fee 2000ugnot (or higher)
Querying Gas Price
You can query the current network gas price using:
gnokey query auth/gasprice -remote https://rpc.gno.land:443
This returns the gas price calculated from the most recently completed block, which is the minimum rate currently required for new transactions.
For more details, see auth/gasprice.
How the Network Adjusts Gas Price
The network automatically adjusts the gas price after each block based on demand:
- Low demand: Price decreases (but never below 1 ugnot/1000 gas)
- High demand: Price increases
The network targets 70% utilization of the maximum block gas limit (3B gas) by default. When blocks exceed this target, prices rise. When blocks fall below it, prices drop. Changes are gradual to avoid sudden price spikes.
Note: Individual validators can also set their own minimum gas price through the
min_gas_prices configuration parameter in their config.toml file. A node
refuses a transaction under its own minimum from its mempool. Paying above the
minimums buys no priority: blocks take transactions in the order they arrived.
Typical Gas Values
Here are some recommended gas values for common operations:
| Operation | Recommended Gas Wanted | Gas Fee at 1ugnot/1000gas |
|---|---|---|
| Simple transfer | 2,000,000 | 2000ugnot |
| Calling a realm function | 2,000,000 | 2000ugnot |
| Deploying a small package | 5,000,000 | 5000ugnot |
| Deploying a complex realm | 10,000,000+ | 10000ugnot |
The fee column is the minimum the network accepts at the initial gas price, one
ugnot per 1000 gas. It rises with the gas price, so
query the current one or run -simulate only rather
than copying these numbers into a script.
Gas Estimation
Use the -simulate only flag to estimate gas usage and the recommended fee
without executing on-chain or incrementing the account sequence number:
gnokey maketx addpkg \
-pkgdir "./hello_world" \
-pkgpath gno.land/p/examplenamespace/hello_world \
-gas-wanted 4000000 \
-gas-fee 4000ugnot \
-remote https://rpc.latest.testnets.gno.land:443 \
-chainid <chain-id> \
-simulate only \
YOUR_KEY_NAME
Put the current testnet's chain ID, listed in Networks,
in place of <chain-id>.
Simulation output, so nothing reached a block:
OK!
GAS WANTED: 4000000
GAS USED: 2590066
HEIGHT: 0
STORAGE DELTA: 1748 bytes
STORAGE FEE: 174800ugnot
TOTAL TX COST: 178800ugnot
EVENTS: [{"bytes_delta":1748,"fee_delta":{"denom":"ugnot","amount":174800},"pkg_path":"gno.land/p/examplenamespace/hello_world"}]
INFO: estimated gas usage: 2590066 (suggested, with 5% margin: 2719570), gas fee: 2720ugnot, current gas price: 1ugnot/1000gas
TX HASH:
PKGPATH: gno.land/p/examplenamespace/hello_world
That is why HEIGHT is 0 and TX HASH is empty. STORAGE FEE is the
storage deposit, locked rather than spent, and
TOTAL TX COST adds it to the gas fee.
Take the suggested figure, 2719570 here, not the raw estimate: gas shifts
between the simulation and the broadcast, and the 5% margin absorbs it. Take the
printed gas fee plus one ugnot, so 2721 here. Rounding inside gnokey can
leave the printed figure one ugnot under the ratio the chain wants, and never
more than one. The broadcast then carries
-gas-wanted 2719570 -gas-fee 2721ugnot.
Gas Optimization Tips
To minimize what a transaction costs:
- Store less: every byte a transaction adds to state locks a storage deposit of 100ugnot on top of its gas. The deposit is most of what storing data costs, so keep only what the realm needs on chain.
- Bound iteration: each iterator step over stored data costs gas, so keep loops over collections short and paginate where a caller sets the size.
- Batch operations: fold several changes into one transaction where you can, so a signature is verified once instead of once per transaction.
- Precompute off chain: do work in your client and send the result, rather than having the realm compute it on every call.
- Test locally first: use
gnodevto measure and tune gas before deploying to a network.
Common Errors
Insufficient fees:
insufficient fees; got: {Gas-Wanted: 2000000, Gas-Fee 1000ugnot}, fee required: 1ugnot/1000gas as block gas price
- Your
--gas-feeis too low. Increase it to meet the minimum required.
Out of gas:
gas used (2600000) exceeds tx's gas wanted (1000000) during operation: simulation
- Your
--gas-wantedis too low. Use-simulate onlyto estimate needed gas, then increase. operation: simulationmeans the default-simulate testcaught it before a block, so nothing was charged.
Not enough deposit:
storage deposit processing encountered one or more errors: not enough deposit to cover the storage usage: requires 206900ugnot for 2069 bytes
- The bytes the message adds lock more than its deposit cap allows: 2069 bytes
lock 206900ugnot here. The cap is the
-max-deposityou passed, or the chain's own ceiling without the flag, per Storage deposits. Pass a-max-depositthat covers what the message locks, or store less.