Skip to content

Gas snapshots

Hardhat can track gas usage across your test runs and save it to snapshot files.

There are two types of snapshots:

  • Function gas snapshots track the gas used by each test function.
  • Snapshot cheatcodes let you capture specific gas measurements or values from within your tests.

To create or update your snapshots, run your tests with the --snapshot flag:

Terminal window
npx hardhat test --snapshot
npx hardhat test solidity --snapshot

Function gas snapshots are only written when all tests pass. Snapshot cheatcodes are always written, even if some tests fail.

To verify that snapshots haven’t changed, use the --snapshot-check flag:

Terminal window
npx hardhat test --snapshot-check
npx hardhat test solidity --snapshot-check

This compares the current test run against your saved snapshots. If anything changes, the command exits with a non-zero code and shows the differences:

Snapshot check failed
Function gas snapshots: 1 changed
CalculatorTest#testAddition
(in test/Calculator.t.sol:34)
Expected (gas): 56852
Actual (gas): 58921 (+3.64%, Δ+2069)
To update snapshots, run your tests with --snapshot

The check only fails when existing values change. Adding or removing snapshots won’t cause a failure.

The .gas-snapshot file records the gas used by each test function. Each line contains the contract name, function name, and gas details:

CalculatorTest#testAddition() (gas: 56852)
CalculatorTest#testSubtraction() (gas: 48291)

For fuzz tests, the file records the number of runs, mean, and median gas usage:

CalculatorTest#testFuzzAddition(uint128,uint128) (runs: 256, μ: 55070, ~: 55040)

When checking snapshots, only the median (~) is compared for fuzz tests.

Snapshot cheatcodes let you capture specific values from within your Solidity tests. These are useful when you want to track something other than the total gas used by a test function.

Use snapshotGasLastCall to capture the gas used by the previous call:

contract CalculatorTest is Test {
Calculator calculator;
function setUp() public {
calculator = new Calculator();
}
function testAdditionGas() public {
calculator.add(1, 2);
vm.snapshotGasLastCall("calculator-add");
}
}

Use startSnapshotGas and stopSnapshotGas to measure the gas used by a block of code:

function testMultipleOperations() public {
vm.startSnapshotGas("multiple-ops");
calculator.add(1, 2);
calculator.multiply(3, 4);
calculator.subtract(10, 5);
vm.stopSnapshotGas("multiple-ops");
}

Use snapshotValue to capture any uint256 value:

function testInitialState() public {
uint256 result = calculator.result();
vm.snapshotValue("calculator-initial-result", result);
}

By default, snapshots are grouped by the test contract name. You can specify a custom group as the first argument:

vm.snapshotGasLastCall("gas-benchmarks", "calculator-add");
vm.snapshotValue("state-checks", "initial-result", calculator.result());

If you capture multiple snapshots with the same group and name, the last value wins.