๐พ Storage Patterns: Packing & Slots
Master storage layout optimization to reduce SSTORE costs
Write efficient smart contracts that save money
Your Progress
0 / 5 completed๐พ Storage Optimization Patterns
Storage is the most expensive resource in Ethereum. A single SSTORE costs 20,000 gas (vs 3 for memory). But the EVM stores data in 32-byte slotsโif you use uint256 for everything, you waste space. Storage packing fits multiple small variables (uint128, uint64, uint32) into one slot, reducing writes by 66-90%. Choosing between mappings vs arrays matters: mappings are O(1) but can't iterate; arrays iterate but cost gas per element. Memory cachingโreading storage once into memory, then operating on memoryโcuts repeated SLOAD costs. Production contracts (Uniswap, Aave) obsess over storage layout. One optimization can save millions in aggregate gas fees.
๐ฎ Interactive: Storage Pattern Comparison
Select a storage pattern to see gas costs, code examples, and when to use each approach.
Unpacked Storage
Each variable occupies full 32-byte slot (wasteful)
// โ BAD: 3 storage slots
uint256 a; // slot 0
uint256 b; // slot 1
uint256 c; // slot 2
// Cost: 3 ร 20,000 = 60,000 gas๐ Storage Packing Rules
struct User { uint128 balance; uint64 timestamp; address addr; } = 1 slot!๐ Mapping vs Array Decision Tree
- โข Sparse data (not every key has a value)
- โข Need O(1) lookups by key (address, uint, bytes32)
- โข Don't need to iterate over all entries
- โข Example:
mapping(address => uint)for balances
- โข Dense data (most indices filled)
- โข Need to iterate over all elements
- โข Small, bounded size (<100 elements)
- โข Example:
address[] ownersfor multisig
- โข Unbounded array iteration (DoS attack vector)
- โข Delete array elements without shifting (leaves gaps)
- โข Store large objects in arrays (high gas per push)
๐ง Memory Caching Pattern
function badLoop() external {
for (uint i = 0; i < 10; i++) {
total += values[i];
// SLOAD: 10 ร 2,100 = 21,000 gas
}
}function goodLoop() external {
uint _total = total; // 1 SLOAD
for (uint i = 0; i < 10; i++) {
_total += values[i];
}
total = _total; // 1 SSTORE
// Savings: 18,900 gas (90%!)
}