⚡ Storage Optimization: Pack Variables & Save Gas

Reduce storage costs by grouping small variables together

⚡ Storage Optimization Techniques

Optimizing storage can reduce gas costs by 40-80%. The key techniques are variable packing, caching, and choosing the right data structures for your use case.

🎯 Interactive: Variable Packing Simulator

Compare unoptimized vs. optimized storage layouts:

contract Unoptimized {
  uint256 a;      // Slot 0 (32 bytes)
  uint8 b;        // Slot 1 (1 byte, wastes 31!)
  uint256 c;      // Slot 2 (32 bytes)
  uint8 d;        // Slot 3 (1 byte, wastes 31!)
  address owner;  // Slot 4 (20 bytes, wastes 12!)
}
Slots Used
5
Wasted Bytes
74
Write Cost
100,000 gas
Read Cost
10,500 gas
Storage Layout:
Slot 0:
uint256 a
Slot 1:
uint8 b
unused (31B)
Slot 2:
uint256 c
Slot 3:
uint8 d
unused (31B)
Slot 4:
address owner
unused (12B)

🎯 Interactive: Gas Cost Comparison

See how optimization affects different operations:

Writing all variables (SSTORE)
Save 40,000 gas
(40% reduction)
❌ Unoptimized
100,000 gas
✅ Optimized
60,000 gas

Optimization Techniques

📦
Variable Packing

Group small variables together to fit in one slot:

✅ uint128 a; uint128 b; // Same slot
❌ uint256 x; uint8 y; // Different slots
💾
Memory Caching

Load storage into memory once, reuse it:

✅ uint temp = storageVar; // Cache
❌ storageVar + storageVar; // 2 SLOADs
🗜️
Data Compression

Use smallest type that fits your data:

✅ uint8 age; // 0-255
❌ uint256 age; // Overkill
🔄
Struct Packing

Order struct fields by size for packing:

✅ uint128, uint128, uint256
❌ uint256, uint128, uint128

Practical Example: User Profile

❌Unoptimized (5 slots)

struct User {
  address wallet;     // Slot 0
  uint256 balance;    // Slot 1
  bool active;        // Slot 2
  uint64 lastSeen;    // Slot 3
  uint8 level;        // Slot 4
}
Write cost: ~100,000 gas
Wasted: 75 bytes

✅Optimized (2 slots)

struct User {
  uint256 balance;    // Slot 0
  address wallet;     // Slot 1 (20 bytes)
  uint64 lastSeen;    // Slot 1 (8 bytes)
  uint8 level;        // Slot 1 (1 byte)
  bool active;        // Slot 1 (1 byte)
  // 2 bytes unused
}
Write cost: ~40,000 gas (60% savings!)
Wasted: 2 bytes only

Advanced: Bit Packing

For ultimate optimization, pack multiple values into a single uint256 using bitwise operations:

// Pack 4 uint64 values into one uint256
uint256 packed = 
  (uint256(a) << 192) | 
  (uint256(b) << 128) | 
  (uint256(c) << 64) | 
  uint256(d);

// Unpack values
uint64 a = uint64(packed >> 192);
uint64 b = uint64(packed >> 128);
uint64 c = uint64(packed >> 64);
uint64 d = uint64(packed);
💡 Result:
  • • 4 values in 1 slot instead of 4 slots (75% storage reduction)
  • • Single SLOAD reads all 4 values (75% read cost reduction)
  • • Single SSTORE writes all 4 values (75% write cost reduction)
  • • Tradeoff: More complex code, higher gas for packing/unpacking operations

💡 Optimization Checklist

✓Order variables by size (largest to smallest)
✓Group small types (uint8, bool, address) together
✓Cache storage reads in memory variables
✓Use smallest type that fits your data range
✓Minimize storage writes (most expensive operation)
✓Use events for historical data (50x cheaper)
✓Consider bit packing for frequently accessed groups
✓Delete unused storage slots for gas refunds