Skip to content
🎉 Welcome to the new Aptos Docs! Click here to submit feedback!
Computing Transaction Gas

Computing Transaction Gas

Aptos transactions by default charge a base gas fee, regardless of market conditions. For each transaction, this “base gas” amount is based on three conditions:

  1. Instructions.
  2. Storage.
  3. Payload.

The more function calls, branching conditional statements, etc. that a transaction requires, the more instruction gas it will cost. Likewise, the more reads from and writes into global storage that a transaction requires, the more storage gas it will cost. Finally, the more bytes in a transaction payload, the more it will cost.

As explained in the optimization principles section, storage gas has by far the largest effect on base gas. For background on the Aptos gas model, see The Making of the Aptos Gas Schedule.

Instruction gas

Basic instruction gas parameters are defined at and include the following instruction types:


nopA no-operation

Control flow

br_trueExecute conditional true branch
br_falseExecute conditional false branch


popPop from stack
ld_u8Load a u8
ld_u16Load a u16
ld_u32Load a u32
ld_u64Load a u64
ld_u128Load a u128
ld_256Load a u256
ld_trueLoad a true
ld_falseLoad a false
ld_const_baseBase cost to load a constant
ld_const_per_bytePer-byte cost to load a constant

Local scope

imm_borrow_locImmutably borrow
mut_borrow_locMutably borrow
imm_borrow_fieldImmutably borrow a field
mut_borrow_fieldMutably borrow a field
copy_loc_baseBase cost to copy


call_baseBase cost for a function call
call_per_argCost per function argument
call_per_localCost per local argument
call_generic_per_ty_argCost per type argument
call_generic_per_localCost generic per local argument


pack_baseBase cost to pack a struct
pack_per_fieldCost to pack a struct, per field
unpack_baseBase cost to unpack a struct
unpack_per_fieldCost to unpack a struct, per field


read_ref_baseBase cost to read from a reference
write_ref_baseBase cost to write to a reference
freeze_refFreeze a reference


cast_u8Cast to a u8
cast_u16Cast to a u16
cast_u32Cast to a u32
cast_u64Cast to a u64
cast_u128Cast to a u128
cast_u256Cast to a u256




bit_orOR: |
bit_andAND: &
xorXOR: ^
shlShift left: <<
shrShift right: >>


orOR: ||
andAND: &&
notNOT: !


ltLess than: <
gtGreater than: >
leLess than or equal to: <=
geGreater than or equal to: >=
eq_baseBase equality cost: ==
neq_baseBase not equal cost: !=

Global storage

imm_borrow_global_baseBase cost to immutably borrow: borrow_global<T>()
mut_borrow_global_baseBase cost to mutably borrow: borrow_global_mut<T>()
exists_baseBase cost to check existence: exists<T>()
move_from_baseBase cost to move from: move_from<T>()
move_to_baseBase cost to move to: move_to<T>()


vec_len_baseLength of a vector
vec_imm_borrow_baseImmutably borrow an element
vec_mut_borrow_baseMutably borrow an element
vec_push_back_basePush back
vec_pop_back_basePop from the back
vec_swap_baseSwap elements
vec_pack_baseBase cost to pack a vector
vec_pack_per_elemCost to pack a vector per element
vec_unpack_baseBase cost to unpack a vector
vec_unpack_per_expected_elemBase cost to unpack a vector per element

Additional storage gas parameters are defined in,, and other assorted source files in aptos-gas-schedule/src/.

IO and Storage charges

The following gas parameters are applied (i.e., charged) to represent the costs associated with transient storage device resources, including disk IOPS and bandwidth:

In Move, one can read from the global state:

storage_io_per_state_slot_readcharged per item loaded from global state
storage_io_per_state_byte_readcharged per byte loaded from global state

For a committed transaction, various things will be written to the ledger history. Notice that the ledger hisotry is subject to pruning and doesn’t occupy permanent space on the disk, hence no storage fee charged for it.

storage_io_per_state_slot_writecharged per state write operation in the transaction output
storage_io_per_state_byte_writecharged per byte in all state write ops in the transaction output
storage_io_per_event_byte_writecharged per byte in all events in the transaction output
storage_io_per_transaction_byte_writecharged per byte in the transaction itself which is also part of the ledger history

The following storage fee parameters are applied (i.e., charged in absolute APT values) to represent the disk space and structural costs associated with using the Aptos authenticated data structure for storing items on the blockchain.

storage_fee_per_state_slot_createallocating a state slot, by move_to(), table::add(), etc
storage_fee_per_state_byteNotice this is charged every time the slot grows in size, not only at allocation time. (However, for simplicity, refunding is only at deletion time. See AIP-65)


Byte-wise fees are similarly assessed on vectors, which consume i=0n1ei+b(n)\sum_{i = 0}^{n - 1} e_i + b(n) bytes, where:

  • nn is the number of elements in the vector
  • eie_i is the size of element ii
  • b(n)b(n) is a “base size” which is a function of nn

See the BCS sequence specification for more information on vector base size (technically a ULEB128), which typically occupies just one byte in practice, such that a vector of 100 u8 elements accounts for 100+1=101100 + 1 = 101 bytes. Hence, per the item-wise read methodology described above, reading the last element of such a vector is treated as a 101-byte read.

Payload gas

Payload gas is defined in, which incorporates storage gas with several payload- and pricing-associated parameters:

min_transaction_gas_unitsMinimum internal gas units for a transaction, charged at the start of execution
large_transaction_cutoffSize, in bytes, above which transactions will be charged an additional amount per byte
intrinsic_gas_per_byteInternal gas units charged per byte for payloads above large_transaction_cutoff
maximum_number_of_gas_unitsUpper limit on external gas units for a transaction
min_price_per_gas_unitMinimum gas price allowed for a transaction
max_price_per_gas_unitMaximum gas price allowed for a transaction
max_transaction_size_in_bytesMaximum transaction payload size in bytes
gas_unit_scaling_factorConversion factor between internal gas units and external gas units

Here, “internal gas units” are defined as constants in source files like and storage_gas.move, which are more granular than “external gas units” by a factor of gas_unit_scaling_factor: to convert from internal gas units to external gas units, divide by gas_unit_scaling_factor. Then, to convert from external gas units to octas, multiply by the “gas price”, which denotes the number of octas per unit of external gas.

Optimization principles

Unit and pricing constants

As of the time of this writing, min_price_per_gas_unit in is defined as aptos_global_constants::GAS_UNIT_PRICE (which is itself defined as 100), with other noteworthy constants as follows:


See Payload gas for the meaning of these constants.

Storage Fee

When the network load is low, the gas unit price is expected to be low, making most aspects of the transaction cost more affordable. However, the storage fee is an exception, as it’s priced in terms of absolute APT value. In most instances, the transaction fee is the predominant component of the overall transaction cost. This is especially true when a transaction allocates state slots, writes to sizable state items, emits numerous or large events, or when the transaction itself is a large one. All of these factors consume disk space on Aptos nodes and are charged accordingly.

On the other hand, the storage refund incentivizes releasing state slots by deleting state items. The state slot fee is fully refunded upon slot deallocation, while the excess state byte fee is non-refundable. This will soon change by differentiating between permanent bytes (those in the global state) and relative ephemeral bytes (those that traverse the ledger history).

Some cost optimization strategies concerning the storage fee:

  1. Minimize state item creation.
  2. Minimize event emissions.
  3. Avoid large state items, events, and transactions.
  4. Clean up state items that are no longer in use.
  5. If two fields are consistently updated together, group them into the same resource or resource group.
  6. If a struct is large and only a few fields are updated frequently, move those fields to a separate resource or resource group.

Instruction gas

As of the time of this writing, all instruction gas operations are multiplied by the EXECUTION_GAS_MULTIPLIER defined in, which is set to 20. Hence, the following representative operations assume gas costs as follows (divide internal gas by scaling factor, then multiply by minimum gas price):

OperationMinimum Octas
Table add/borrow/remove box240
Function call200
Load constant130
Globally borrow100
Read/write reference40
Load u128 on stack16
Table box operation per byte2

(Note that per-byte table box operation instruction gas does not account for storage gas, which is assessed separately).

For comparison, reading a 100-byte item costs ri+100rb=3000+1003=3300r_i + 100 * r_b = 3000 + 100 * 3 = 3300 octas at minimum, some 16.5 times as much as a function call, and in general, instruction gas costs are largely dominated by storage gas costs.

Notably, however, there is still technically an incentive to reduce the number of function calls in a program, but engineering efforts are more effectively dedicated to writing modular, decomposed code that is geared toward reducing storage gas costs, rather than attempting to write repetitive code blocks with fewer nested functions (in nearly all cases).

In extreme cases it is possible for instruction gas to far outweigh storage gas, for example if a looping mathematical function takes 10,000 iterations to converge; but again this is an extreme case and for most applications storage gas has a larger impact on base gas than does instruction gas.

Payload gas

As of the time of this writing, transaction/ defines the minimum amount of internal gas per transaction as 1,500,000 internal units (15,000 octas at minimum), an amount that increases by 2,000 internal gas units (20 octas minimum) per byte for payloads larger than 600 bytes, with the maximum number of bytes permitted in a transaction set at 65536. Hence, in practice, payload gas is unlikely to be a concern.