Make it cheap · Intermediate
Gas & storage
NEAR contracts pay two separate costs: gas for computation, burnt on every call, and storage staking, NEAR that stays locked for every byte the contract stores, including its own code. Most savings come from understanding which of the two a pattern affects.
This module collects practical patterns for cutting both: measuring before optimising, choosing collections, shrinking state and Wasm, making users pay for the storage they add, budgeting gas for cross-contract calls, and reclaiming locked NEAR when data is no longer needed. Examples use near-sdk 5.x.
10 lessons~60 min30 quiz questionsFree · no sign-up
What you’ll learn
- Tell gas fees apart from storage staking, and know who pays each
- Measure gas with
env::used_gas(), transaction outcomes and near-workspaces sandbox tests - Pick between
LookupMap,IterableMap,Vectorand friends, with safe storage prefixes - Estimate the bytes and NEAR each stored entry costs, and shrink them
- Charge users for storage with deposits and refunds, or the NEP-145 standard
- Keep the root contract struct small with lazily loaded state
- Configure a size-optimised release build and keep Wasm small
- Budget static gas and gas weights for cross-contract calls and callbacks
- Paginate views and keep every loop bounded
- Release staked NEAR by deleting data, migrating old state and removing unused accounts
Lessons
1. Fundamentals
- How NEAR fees work: gas vs storageHow NEAR fees work: gas (measured in Tgas) pays for compute and is burnt, while storage staking locks NEAR per byte and is released when data is deleted.
- Measure gas before you optimiseMeasure NEAR gas before optimising: read env::used_gas() and env::prepaid_gas(), check gas burnt per receipt, and print gas in near-workspaces sandbox tests.
2. State & storage
- Pick the right collectionPick NEAR SDK store collections for gas: LookupMap vs IterableMap vs Vector, why a Vec or HashMap in contract state burns gas, and unique storage prefixes.
- Shrink your state, byte by byteShrink NEAR contract state to cut storage staking: Borsh sizes, short prefixes, numbers instead of strings, u64 vs u128, and per-entry byte math in NEAR.
- Make users pay for their storageCharge users for the NEAR storage they add: measure env::storage_usage() before and after writes, require a deposit, refund the excess, or use NEP-145.
- Load only what a call needsKeep NEAR contract root state small to save gas: LazyOption for big values, store collections that load per key, and caching reads within a single call.
4. Calls
- Budget gas for cross-contract callsBudget gas for NEAR cross-contract calls: with_static_gas, with_unused_gas_weight, reserving gas for the callback, and batching actions into one receipt.
- Paginate views, bound every loopPaginate NEAR view methods with from_index and limit, cap loop sizes, and never iterate an unbounded collection in a change method that can run out of gas.