Skip to Content
Supra Layer 1SupraMVMProfiling a Transaction's Gas

Profiling a Transaction’s Gas

Gas profiling needs a Supra CLI and an RPC node from v12.0.0 on. It is available on Devnet only. It is not yet on Testnet or Mainnet.

--profile-gas reports where a Move transaction’s gas goes, without submitting it. The RPC node simulates the transaction under a gas profiler, and the CLI writes an HTML report of the gas each call, operation and storage write took.

Profile a transaction

supra move tool run, supra move tool run-script and supra move tool publish take --profile-gas. Add it to the command that would send the transaction:

supra move tool run --function-id '<ADDRESS>::<MODULE>::<FUNCTION>' --args <ARGS> --profile-gas
supra move tool publish --package-dir <PACKAGE_DIR> --profile-gas

The transaction is never submitted, and nothing on chain changes. The CLI signs it as --simulate does, with a signature that does not verify, so it does not read the profile’s private key. --profile-gas cannot be combined with --simulate.

Gas is chosen as for --simulate: --gas-unit-price and --max-gas if given, otherwise the node’s gas price estimate and the most gas the sender’s balance pays for. The sender’s account must exist on chain, so fund it first, for example from the faucet.

The command prints the height of the state the node simulated against, the gas used and how the transaction ended, then the report’s directory:

Profiled on the RPC node against the state at height <HEIGHT>: gas_used=<GAS>, status=success Gas report saved to gas-profiling/txn-<SENDER>-<SEQUENCE_NUMBER>-<PAYLOAD>-<NANOS>

With supra --stdout json, the result is {"GasProfile": {"state_height": …, "outcome": …, "gas_used": …, "report_dir": …}}.

The report

The report is written to gas-profiling/txn-<SENDER>-<SEQUENCE_NUMBER>-<PAYLOAD>-<NANOS>/ under the directory the command runs in. <PAYLOAD> names the entry function’s address, module and function, or is script. In the Supra CLI’s Docker container, run the command from /supra/move_workspace, which is bind mounted from the host, to open the report on the host.

The directory holds:

FileContents
index.htmlThe report. Open it in a browser. It has a Summary of the totals, the flame graphs, and the tables Execution and IO by operation, Execution and IO by call and Storage.
execution-and-io.svgA flame graph of execution and IO gas by call. Written when the transaction used execution or IO gas.
storage.svgA flame graph of the storage fee by write. Written when the transaction paid a storage fee.

Execution and IO gas is counted in internal gas units, which the tables show converted to gas units. The flame graphs count internal gas units, and the report states how many make one gas unit. Storage fees and refunds are in quants.

Calls with the same name under the same parent are shown as one entry. The node bounds the size of a profile, so a large transaction’s report can contain:

  • (other) entries, which hold the gas of calls, operations or writes that did not fit in the profile. Totals are the same with or without them.
  • names cut short and ending with …;
  • (unnamed type) in place of a type the VM could not name.

A transaction that does not succeed

A transaction that would abort, run out of gas or be discarded is still profiled, and its report is written. The command then exits with a failure status, and its error says how the transaction ended and where the report is:

Command Aborted Reason(The transaction did not succeed when the RPC node simulated it against the state at height <HEIGHT>. Status: failed: Move abort with code <CODE> in <ADDRESS>::<MODULE>. Gas used: <GAS>), Action(Read the gas report saved to gas-profiling/txn-<SENDER>-<SEQUENCE_NUMBER>-<PAYLOAD>-<NANOS>)

The status is failed: out of gas, failed: Move abort with code <CODE> in <LOCATION>, failed: execution failure at code offset <OFFSET> of function <FUNCTION> in <LOCATION>, discarded: <STATUS_CODE> or retry.

When the command fails without a report

CauseWhat the CLI reports
The RPC node does not serve gas profiles: it answered 404 or 405.<NODE> answered <STATUS> for POST <PATH>: the node does not serve gas profiles. It runs a release without the gas-profile endpoint, or its operator has not enabled it (rest_limits.gas_profile.enabled)
The transaction is a multisig transaction. Nothing is sent.--profile-gas cannot profile a multisig payload; it profiles entry functions, scripts and automation registrations
The node answered 400 or 413, or a proxy in front of it answered 503.<NODE> did not profile the transaction (<STATUS>): <REASON>

413 means the transaction is over the node’s request body size limit.

Serving gas profiles from an RPC node

An RPC node serves gas profiles at POST /rpc/v4/transactions/simulate/gas-profile only when its config.toml enables them. The endpoint is off by default; while it is off, the route is not registered, a request is answered 404, and the node’s OpenAPI document leaves it out.

# config.toml [rest_limits.gas_profile] enabled = true max_tree_nodes = 4096 max_operation_rows = 1024 max_name_bytes = 256
SettingDefaultAcceptedBounds
enabledfalseWhether the route is registered.
max_tree_nodes409619 to 4294967295Nodes the two cost trees of one profile hold together. A call or write that does not fit is counted in an (other) node.
max_operation_rows10245 to 4294967295Rows of one profile’s operation table. An operation that does not fit is counted in its kind’s (other) row.
max_name_bytes25617 to 16777216Length of one name in a profile, as JSON. A longer name is cut.

A node started with a value outside its accepted range refuses the configuration and names the field. The three limits together bound the memory one profile holds, and a node whose limits would let one profile hold more than 64 MiB does not start. The defaults allow about 5.4 MiB.

A profile runs on the blocking workers that simulation, views and transaction lookups share, under their permits, and its work is bounded by the gas limits its simulation runs under. The node counts requests in the metric rpc.gas_profile_requests, by outcome (served, refused or failed), and measures the profiles it serves with rpc.gas_profile_duration and rpc.gas_profile_response_bytes.

The request and response are described under the endpoint on the node’s API page, for Devnet https://rpc-devnet.supra.com/docs .

Last updated on