If you've ever sent tokens or interacted with a smart contract on Ethereum or similar networks, you've probably noticed you paid more than just the amount you were trying to send. That extra cost is what we call a "gas fee" in the blockchain world. In traditional finance, this would be analogous to a transaction fee, but with some important differences that make optimisation critical.
The process of lowering the quantity of gas required to carry out smart contracts and transactions is known as gas optimisation. If developers can reduce the gas consumption of blockchain interactions, they'll make these applications significantly more affordable for users, leading to more accessible decentralised applications.
This article explores the nuanced field of gas optimisation—a somewhat under-documented collection of techniques and strategies that can reduce transaction costs by as much as 20%.
Understanding Blockchain Gas
Gas is the unit that measures computational effort required to execute operations on the Ethereum blockchain. But why do we need to measure computation in the first place?
Blockchains like Ethereum aren't just ledgers storing balances—they're decentralised computers. Every
Gas Limit and Gas Price
When executing a transaction, two key parameters determine its cost: gas limit and gas price. These values influence how much you pay and whether your transaction successfully executes.
-
Gas Limit: The maximum amount of gas a user is willing to allocate for a transaction. If the transaction requires more gas than the limit set, it will fail.
-
Gas Price: The amount of Ether a user is willing to pay per unit of gas, measured in gwei (1 gwei = 0.000000001 ETH). Higher gas prices incentivise miners to prioritise processing the transaction.
Why Gas Optimization Matters
Gas optimisation isn't just a technical concern—it has direct economic and user experience implications. Whether you're building DeFi protocols, NFT platforms, or Layer 2 applications, reducing gas costs can make the difference between a viable product and one that users abandon due to inefficiencies. Here’s why it matters:
A. Economic Impact
Direct Cost Savings
Gas optimisation directly translates to lower transaction costs. During network congestion, fees can spike dramatically—during peak periods, a single complex transaction could cost hundreds or even thousands of dollars. By reducing gas consumption by even 10-20%, developers can save users significant amounts over a contract's lifetime.
Scalability for Business Models
Many DeFi protocols and NFT platforms operate on razor-thin margins. Gas costs that aren't optimized can make entire business models unviable. For instance, a DeFi protocol that requires multiple contract interactions could become unusable if each transaction costs more than the expected yield.
B. User Experience Considerations
Transaction Success Rates
Inefficient contracts with unpredictable gas costs lead to failed transactions when users underestimate required gas limits. Each failed transaction still costs the user gas without achieving the intended result, creating a frustrating experience.
Competitive Advantage
Users actively seek out platforms with lower gas costs. Projects like Uniswap v3 gained significant market share partly due to gas optimisations that reduced swap costs by 30-50% compared to earlier versions.
For developers building on L2 solutions or sidechains, optimisation is still crucial—while gas costs may be lower in absolute terms, the same principles apply for creating efficient, responsive applications.
Gas Costs in Ethereum
So far we have discussed gas costs in a broad sense. Let's shift gears a little and discuss how gas costs on the Ethereum chain are determined.
Ethereum Virtual Machine (EVM) and Opcode Costs
At the heart of Ethereum lies the Ethereum Virtual Machine (
When you write smart contracts in Solidity, they get compiled down to EVM bytecode, which consists of a series of instructions called
What makes this relevant to gas optimisation is that each opcode has a fixed gas cost assigned to it, carefully calibrated to reflect its computational intensity, memory usage, and storage requirements.
Storage vs. Computation Costs
Understanding the difference between storage and computation costs is fundamental to effective gas optimisation. These two categories represent significantly different magnitudes of expense in the EVM.
Storage Costs: Storage operations are by far the most expensive gas operations in Ethereum. This is by design—data written to the chain must be stored permanently by every full node in the network.
Computation Costs: In contrast, arithmetic and control flow procedures are inexpensive when done separately; when combined, they can have a big impact on complicated contracts.
Gas Cost Trends Over Time
Updates to Ethereum, network congestion, and modifications to gas pricing algorithms are some of the reasons that affect gas prices. For optimisation to be effective, these patterns must be monitored. For example, the
Principles of Gas Optimization
When approaching gas optimisation, it's important to understand that not all code improvements will yield the same benefits. Some strategies offer dramatic savings, while others provide only marginal improvements. In this section we will explore some concrete concepts for optimising gas.
Minimizing Storage Operations
Storage operations dominate gas costs in most contracts, so minimising them should be your first optimisation priority. Each SSTORE operation (writing to storage) costs 100+ gas for a new slot, orders of magnitude more expensive than computation.
Efficient Data Structures
Your choice of data structures can dramatically impact gas consumption. While Solidity offers similar data structures to other languages, their gas implications differ significantly:
- Arrays vs. Mappings: Arrays have lower access costs for sequential data but higher costs for insertions/deletions. Mappings have constant-cost operations regardless of size but can't be iterated through directly.
- Bytes vs. Strings: For raw data, bytes are more gas-efficient than strings.
- Fixed Arrays vs Dynamic Arrays: Fixed-size arrays avoid the overhead of length tracking.
Cutting Down on Computational Complexity
While computation is cheaper than storage, complex algorithms can still consume significant gas:
- Avoid quadratic complexity (O(n²)) algorithms whenever possible
- Consider implementing gas-intensive calculations off-chain
Making Use of Pre-compilation Contracts
Ethereum includes several
- ECRECOVER (address 0x1) for signature verification
- SHA256 (address 0x2) for the SHA-256 hash function
- RIPEMD160 (address 0x3) for the RIPEMD-160 hash function
- IDENTITY (address 0x4) for memory copying
- MODEXP (address 0x5) for modular exponentiation
Using these for appropriate operations is substantially cheaper than implementing the same functionality in Solidity.
Gas Optimization Techniques
Now that we've covered the fundamental principles, let's explore specific techniques you can apply in your smart contracts.
Loop Unrolling
Loop unrolling replaces loop iterations with explicit, sequential operations. While this makes code longer and less readable, it eliminates the gas costs associated with loop control (incrementing counters, checking conditions)
Inlining Functions
Function calls in Solidity incur gas costs (around 40-100 gas depending on complexity). For small, frequently called functions, inlining them—replacing the function call with the function's code—can save significant gas.
Modern Solidity compilers can automatically
Using Fixed-Size Data Types
Fixed-size types like uint256 or bytes32 are more gas-efficient than dynamic types like string or bytes. They have predictable storage patterns and don't require additional operations to track length.
When working with strings or text, if you know the maximum length will be 32 bytes or less, using bytes32 instead of string can save substantial gas.
Packing Variables
The EVM operates on 32-byte (256-bit) storage slots. You can pack multiple smaller variables into a single slot to reduce storage operations.
Advanced Methods of Optimisation
Beyond the fundamental techniques we've discussed, there are more sophisticated approaches that can dramatically reduce gas costs in certain scenarios.
Patterns of Proxy and Upgradeability
Proxy patterns separate contract logic from storage by using a proxy contract that delegates calls to an implementation contract. This separation offers two key gas benefits:
First, it reduces deployment costs for upgrades since only the implementation contract needs to be redeployed, not the storage contract. For complex contracts, this can save hundreds of thousands of gas during upgrades.
Second, it allows for more targeted optimizations by isolating logic from data. Each implementation can be highly optimized for its specific purpose without worrying about storage layout compatibility issues.
The most common proxy patterns include the
Stateless Contracts
Stateless contracts minimize or eliminate on-chain storage, instead relying on external data passed in function calls. By pushing state management off-chain, these contracts avoid expensive SSTORE and SLOAD operations.
A common implementation uses cryptographic proofs to verify off-chain state. For example, a contract might store only a Merkle root, then users provide Merkle proofs along with their transactions to prove certain state conditions.
Layer 2 Solutions
Layer 2 scaling solutions process transactions off the main Ethereum chain while inheriting its security guarantees. Popular L2 approaches include:
- Optimistic Rollups (like Optimism and Arbitrum) that assume transactions are valid but allow for challenges
- ZK-Rollups (like
zkSync and StarkNet) that use zero-knowledge proofs to validate transaction batches - Sidechains (like Polygon) that operate as separate blockchains with their own consensus mechanisms
Gas Token Mechanisms
Gas token mechanisms exploit the EVM's gas refund system by storing gas during periods of low network activity and releasing it during high congestion. This works because the EVM refunds gas when storage is freed or contracts are destroyed.
While clever, this approach has become less effective since
Tools for Gas Optimization
Before diving into specific optimization techniques, it's important to understand the tools available to help you identify and address gas inefficiencies.
Solidity Optimizer
The Solidity compiler includes a built-in optimizer that can significantly reduce gas costs with minimal effort. It works by analyzing your code and applying various transformations to generate more efficient bytecode.
When you compile Solidity code, you can specify an optimization level, which represents the number of optimization rounds the compiler will perform. Higher values yield better gas efficiency but may increase compilation time.
Gas Profiling Tools
Gas profiling tools give you visibility into where your contract is consuming gas, similar to how profilers work in traditional software development. These tools are essential for targeting your optimization efforts effectively:
Remix IDE offers a built-in gas profiler that breaks down gas costs by function and provides a detailed view of opcodes generated.Hardhat includes gas reporting plugins that track gas usage across test suites, allowing you to monitor how code changes impact gas consumption.
Static Analysis Tools
Static analysis tools examine your code without executing it, identifying potential gas inefficiencies:
Slither can detect common gas anti-patterns and suggest optimizationsSolhint includes linting rules specifically for gas efficiency
Debugging and Testing Frameworks
Comprehensive testing is critical when optimizing for gas—it's easy to introduce bugs while pursuing efficiency:
- Foundry provides powerful gas snapshots to track gas usage across test runs and detect regressions
- Truffle offers gas usage reports and debugging capabilities to step through transaction execution
DeFi protocols often face the most significant gas optimization challenges due to their complex interactions. Analyzing Uniswap V3's implementation reveals several key optimizations:
- Strategic use of bit packing to store position data efficiently
- Careful separation of read-only and state-changing functions
- Implementation of a tick system that minimizes storage operations during swaps
These optimizations enabled Uniswap V3 to offer concentrated liquidity positions without prohibitive gas costs, demonstrating how architectural design choices can have more impact than code-level tweaks.
Challenges and Trade-offs
Security vs. Optimization
Pursuing gas efficiency sometimes introduces security risks. For instance, assembly code bypasses Solidity's safety checks, and complex packing schemes can lead to overflow vulnerabilities if not carefully implemented.
The key is to prioritize security, then optimize within those constraints. Always consider whether a gas saving justifies increased complexity or potential attack vectors.
Readability vs. Efficiency
Highly optimized code is often harder to understand and maintain. Consider this trade-off carefully—in many cases, slightly higher gas costs are worth the benefit of code that future developers (including yourself) can easily understand and safely modify.
Use comments liberally to explain optimization techniques, especially when using approaches like assembly or bit manipulation.
Future-Proofing Contracts
Gas costs change with network upgrades. What's optimal today may not be tomorrow. Some strategies for future-proofing include:
- Modular design that allows replacing gas-intensive components
- Using proxy patterns to enable upgrades
- Avoiding optimizations that rely on specific gas refund mechanisms or quirks that might change
Gas Models on Different Blockchains
Different blockchains implement fundamentally different approaches to resource pricing:
- Polygon prioritizes transaction throughput with significantly lower gas prices than Ethereum. While this reduces overall costs, it doesn't eliminate the need for optimization—especially for high-volume applications where even small per-transaction savings multiply.
- BNB Smart Chain uses a similar gas model to Ethereum but with different base costs for certain operations. Its higher block gas limit allows more complex operations in a single transaction.
- Solana takes an entirely different approach with its resource model, focusing on compute units rather than gas. Optimizing for Solana requires different techniques focusing on program size and computational efficiency.
- Layer 2 Solutions like Arbitrum and Optimism inherit Ethereum's gas model but modify costs based on their specific implementations. Understanding their compression and execution models is key to optimization.
Conclusion
The effect of gas optimization is significantly improving scalability and cost effectiveness. Developers can save a lot of gas by knowing the fundamentals of gas optimization, utilizing cutting-edge methods, and utilizing the appropriate tools.
But because gas optimization has its own set of difficulties, engineers have to carefully weigh efficiency, security and readability.
Because of the ongoing growth of blockchain technology, gas optimization will continue to be a major area of research interest encouraging the creation of fresh strategies and instruments to deal with the ever changing environment.