DEV Community

Loading Blocks
Loading Blocks

Posted on

Saving Real Money: Rethinking Solidity Gas Optimization

Introduction: Saving Gas from Unexpected Places

In Ethereum development, Gas fees are a very real financial burden. Every deployment, transaction, and state change costs actual money. While most developers look for ways to cut Gas usage, many of the most effective optimization tricks are actually counterintuitive.

The key to real Gas savings lies in understanding two fundamental principles of the EVM (Ethereum Virtual Machine):

Storage operations are extremely expensive.

The EVM is built around a 256-bit (32-byte) word size.

With these principles in mind, let’s dive into five surprising optimization techniques.

1. Variable Order Determines Cost — The Magic of Variable Packing

Solidity stores state variables in 32-byte storage slots.

Multiple smaller variables can be packed into a single slot, but only if declared consecutively.

Each new slot written requires an expensive STORE operation.

By rearranging variable declarations, you can reduce the number of slots used.

Example:

Unoptimized: variables consume 3 slots.

Optimized: variables consume 2 slots by grouping uint8, uint8, and uint128 together.

👉 Key insight: Put small variables next to each other to maximize packing and minimize storage costs.

2. Smaller Variables Are Always Cheaper? Not Really.

A common misconception: using uint8 instead of uint256 always saves Gas.

In reality, the EVM natively operates on 256-bit words.

If a small type is not packed, the EVM has to extend it to 256 bits before performing arithmetic, costing extra Gas.

Rule: Use smaller types only if they can be packed. Otherwise, stick with uint256.

3. Delete Variables for a Gas Refund

The delete keyword resets a variable to its default value and signals the EVM that storage is being freed.

As a result, the transaction receives a Gas refund.

In contrast, x = 0 just performs an STORE with no refund.

Refunds are capped at about 50% of the transaction Gas used to prevent abuse.

👉 Key insight: Always use delete instead of manual reset when clearing storage.

4. Loop Trap: Cache Storage Variables

Reading (SLOAD) or writing (STORE) inside a loop is extremely costly.

Naïve approach: Every iteration accesses storage directly → 100 costly reads/writes.

Optimized approach: Cache the value into a local memory variable before the loop, then write back only once.

This transforms 100 storage operations into just 1, saving massive Gas.

👉 Key insight: Always cache storage variables in memory when used repeatedly inside loops.

5. calldata vs memory — No Free Lunch? Actually, Yes.

calldata: Acts like a read-only “window” into the transaction input. No copying, extremely cheap.

memory: Requires copying data from calldata into a new memory allocation. More expensive, but allows modifications.

For external functions where parameters don’t need modification, calldata is always the cheaper and safer choice.

👉 Key insight: Use calldata for read-only parameters (arrays, strings, structs) in external functions.

Conclusion:

True optimization is not about memorizing rules, but about understanding the EVM’s cost model:

Storage is expensive.

Memory is cheap.

calldata is almost free.

Computation is cheap, but state changes are not

Top comments (0)