
Solana vs. Ethereum: Which Blockchain Developer Hire Fits Your B2B FinTech Project?
Gas optimization is one of the most important skills a Solidity developer must learn. Gas directly affects how much users pay to interact with your smart contracts. Efficient gas usage means cheaper execution, faster transactions, and higher adoption of your decentralized application (dApp). In this blog, we will break down the top 5 gas optimization techniques every Solidity developer should master — explained clearly, with examples, meanings, and best practices.
Before we dive in, let’s define a few key terms to build our foundation.
What Is Gas in Ethereum?
In the world of Gas Ethereum and other blockchains that support smart contracts, gas is a unit that measures how much work is required to perform an operation. Every computation, data store, or state change in a smart contract costs gas.
Gas is paid in Ether (ETH) by the user executing the transaction. High gas costs can make a user hesitate or leave your dApp altogether.
Why Is Gas Optimization Important?
User Cost Efficiency
Cheaper transactions attract more users.Scalability
Efficient contracts can handle more interactions and scale better across users.Network Congestion
Optimized gas saves network resources, which helps reduce congestion.
In this blog, we’ll explore practical methods to reduce gas usage and optimize your smart contracts. These techniques are essential whether you're a beginner or advanced Solidity developer.
Minimize Storage Writes
Why Storage Costs So Much
In Ethereum, data storage is expensive. Writing to the blockchain (i.e., storing state variables) uses a lot of gas, because the data must be permanently recorded across all nodes in the network.
For an overview of Ethereum’s storage costs, see Ethereum Virtual Machine Common expensive operations include:
Writing to storage (SSTORE)
Updating storage values
Optimization Strategies
a) Use Memory and Stack Whenever Possible
Variables stored in memory or the stack are cheaper than persistent storage.
function calculate(uint a, uint b) public pure returns(uint) {
uint result = a + b; // stored in memory, cheap
return result;
}
b) Reduce Redundant Writes
If a value isn’t changing, don’t write it again.
if (x != newValue) {
x = newValue;
}
c) Pack Variables
Smaller types like uint8, bool, address, etc., can pack into a single storage slot if declared together.
contract Packed {
uint128 a;
uint128 b; // two 128-bit values fit into one 256-bit slot
}
Why This Matters
Every SSTORE operation can cost hundreds or thousands of gas units. Reducing storage usage saves real ETH — especially when thousands of users interact with your contract.

Favor Short-Circuit Evaluation and Efficient Conditionals
Branching logic (like if, else, require) carries gas cost. Using conditions efficiently can save gas flow and even prevent unnecessary computation.
What Is Short-Circuit Evaluation?
Short-circuit evaluation means stopping evaluation as soon as the result is known.
For example:
if (a > 0 && expensiveFunction()) {
// do something
}
If a > 0 is false, expensiveFunction() won’t run, saving gas.
Smart Use of require() and assert()
require() should validate user inputs or state before execution.
assert() should check for invariants — conditions that should never fail.
Proper usage prevents expensive operations from executing under invalid conditions.
require(balance >= amount, "Insufficient balance");
If a condition fails early with require, the remaining logic won’t run — saving gas.
Avoid Multiple if Checks When Possible
Multiple independent if conditions may cost more than a single structured check.
Instead of:
if (x > 10) { ... }
if (y > 20) { ... }
Use:
if (x > 10 && y > 20) { ... }

Use Efficient Data Types and Structures
Gas costs vary with every type. Efficient use of types and structures directly impacts costs.
Choose the Smallest Sufficient Type
Avoid using uint256 everywhere if you only need a small range.
Type | Typical Use |
uint8 | Small counters |
uint16 | Small numeric values |
uint256 | Default for computations |
But: Solidity pads values into 32-byte slots, so always group smaller types together.
Use calldata Over memory for External Functions
When accepting function arguments that are read-only (like arrays), use calldata.
function process(uint[] calldata values) external {
// cheaper than uint[] memory
}
calldata is cheaper because it avoids making a copy of values into memory.
Use mapping Instead of Arrays When Possible
Dynamic arrays can become expensive when iterated or resized.
mapping(address => uint) public balance;
Mapping operations are constant time and cheaper than looping through arrays.
Leverage View and Pure Functions
Mark functions as view or pure when they don’t modify state.
view: function reads state, but doesn’t write.
pure: function neither reads nor writes state.
function sum(uint a, uint b) public pure returns(uint) {
return a + b;
}
Functions marked as view or pure can be optimized by the EVM and are free when called externally (without transaction).
Use Internal/Private Over Public When Possible
Public functions have automatic getter code which costs gas.
Prefer:
function _calculateInternal() internal {...}
Instead of:
function calculate() public {...}
Unless external access is required.
Move Constant and Immutable Variables
Using the keywords constant and immutable can reduce gas:
constant: value known at compile time
immutable: value set once at construction
These variables are stored in the contract bytecode rather than storage — which saves gas.
uint256 public constant MAX_SUPPLY = 1000000;
address public immutable owner;
constructor() {
owner = msg.sender;
}
Gas Savings in Action
Both constant and immutable values don’t require a storage read on every access, which is cheaper than regular state variables.

BONUS: Understand the EVM and Gas Costs
Though not strictly a “technique,” understanding the Ethereum Virtual Machine (EVM) and its cost for different operations helps you design smarter contracts.
Here are some common costs:
Operation | Cost Reason |
SSTORE | Writing to storage |
SLOAD | Reading from storage (less than write) |
CALL | External contract call |
Arithmetic | Cheaper operations like add, sub, mul |
Comprehensive Examples: Before and After Optimization
Let’s look at an unoptimized contract and then optimize it using the techniques above.
Unoptimized Version
pragma solidity ^0.8.0;
contract Unoptimized {
uint[] public data;
function addData(uint value) public {
data.push(value);
}
function sumData() public view returns(uint) {
uint total = 0;
for (uint i = 0; i < data.length; i++) {
total += data[i];
}
return total;
}
}
Problems
Uses dynamic array and loops over it — costly.
Always uses public state access.
No usage of efficient types.
Optimized Version
pragma solidity ^0.8.0;
contract Optimized {
uint256 public total; // avoid looping
mapping(uint256 => bool) public exists;
function addData(uint256 value) public {
if (!exists[value]) {
exists[value] = true;
total += value;
}
}
function getTotal() public view returns(uint256) {
return total;
}
}
Benefits
Replaced dynamic array with mapping — no iteration over an array.
Avoids multiple writes for same values.
Uses efficient types.
Gas Profiling Tools Every Developer Should Use
Optimizing code manually is vital, but tools speed up the process. Here are some tools that help you analyze gas:
Solidity Compiler Output
The compiler gives an estimate of gas for each function.Remix IDE Gas Profiler
Shows gas used by each function.Hardhat / Truffle with Gas Reports
Plugins like hardhat-gas-report can show gas usage per test.Tenderly Gas Insights
Advanced profiling and historical gas tracking.
These tools help validate your optimizations and discover hidden gas “hot spots”.
Common Mistakes to Avoid
Here are some pitfalls that often lead to higher gas consumption:
Unnecessary Loops
Loops over large arrays cost a lot of gas.
Storing Redundant State
Avoid saving values that can be computed.
Inefficient Data Types
Using default uint256 everywhere.
Unoptimized Error Messages
Too long error strings cost slightly more gas.
Gas Optimization Checklist
Before deploying your contract, run through this checklist:
Do you minimize storage writes?
Are you using calldata where possible?
Do you use efficient data structures (mapping vs array)?
Are your functions marked view or pure when appropriate?
Are constants and immutable values used?
Have you profiled gas usage with tools?
Real-World Impact of Gas Savings
Let’s look at an example:
Imagine your contract charges users a fee of 100,000 gas per interaction. If optimization reduces this to 80,000 gas, that’s a 20% reduction.
If 10,000 users interact in a month at an average price of 100 gwei, the saving is:
10,000 × 20,000 gas × 100 gwei
= 200,000,000,000 gwei
= 0.2 ETH
That’s real savings for your users — and more adoption for your dAppConclusion
Optimize Loops and Iterations Carefully
Loops are one of the most common sources of excessive gas consumption in Solidity. Every iteration multiplies the cost of the operations inside it, which means a loop that looks harmless in testing can become prohibitively expensive in production.
Why Loops Are Dangerous on Ethereum
Unlike traditional systems, Ethereum transactions have a block gas limit. If a loop grows too large, the transaction will revert entirely. This is especially risky with user-controlled arrays.
According to the Ethereum Yellow Paper, gas is charged per opcode execution, making repetitive operations inherently costly.
Best Practices for Loop Optimization
1. Avoid Unbounded Loops
Never loop over arrays whose size can grow indefinitely.
Instead of:
for (uint i = 0; i < users.length; i++) { ... }
Use:
Mappings
Pagination
Off-chain indexing (The Graph)
2. Cache Array Lengths
uint len = users.length;
for (uint i = 0; i < len; i++) { ... }
This avoids repeated SLOAD operations.
3. Move Expensive Logic Outside Loops
Compute values once and reuse them inside the loop.
Reduce External Contract Calls
External calls (CALL, DELEGATECALL, STATICCALL) are among the most expensive EVM operations and introduce security risks alongside gas overhead.
Why External Calls Cost More Gas
An external call:
Switches execution context
Passes calldata
Handles return data
Adds failure risk
This makes it significantly more expensive than internal function calls.
Optimization Strategies
1. Cache External Results
Instead of calling an oracle or another contract multiple times in one transaction, store the result locally.
2. Batch External Calls
Design contracts to perform a single external call that returns multiple values.
3. Prefer Libraries Over External Contracts
Internal libraries are compiled into bytecode, avoiding external calls entirely.
Use Custom Errors Instead of Revert Strings
Since Solidity 0.8.4, custom errors offer a powerful way to reduce gas while improving clarity.
Why Revert Strings Are Expensive
Revert strings are stored in contract bytecode and consume gas proportional to their length.
Example:
require(balance >= amount, "Insufficient balance for withdrawal");
Optimized Alternative: Custom Errors
error InsufficientBalance(uint available, uint required);
if (balance < amount) {
revert InsufficientBalance(balance, amount);
}
This approach:
Reduces deployment gas
Lowers runtime gas
Improves debugging
Prefer Events Over On-Chain Storage for Logging
Storing data on-chain is expensive. Logging data via events is significantly cheaper and often sufficient.
Storage vs Events
Method | Gas Cost | Accessibility |
Storage | High | On-chain |
Events | Low | Off-chain |
When to Use Events
Use events for:
Transaction history
User activity
Analytics
Indexing by dApps
event Transfer(address indexed from, address indexed to, uint amount);
Ethereum events and logs
Inline Functions and Avoid Excessive Abstraction
While abstraction improves readability, it can increase gas costs if overused.
Inline vs Function Calls
Internal function calls add stack operations and jump instructions. For small logic blocks, inlining can be cheaper.
Practical Balance
Inline trivial arithmetic
Abstract complex logic
Measure with gas profiling tools
Understand Storage Refunds and Gas Refund Mechanics
Ethereum refunds gas when storage is cleared, which can be strategically leveraged.
Example
delete balances[msg.sender];
This triggers a gas refund, reducing total transaction cost.
Important Notes
Refunds are capped
EIP-3529 reduced refund amounts
Still useful for state cleanup
Ethereum gas refund mechanics
Optimize Contract Deployment Size
Gas optimization doesn’t stop at runtime — deployment gas matters, especially for enterprise-grade systems.
Deployment Cost Drivers
Large revert strings
Excessive inheritance
Unused functions
Optimization Techniques
Use libraries
Remove dead code
Minimize constructor logic
Solidity contract size limits
Use Layer 2 Compatibility-Friendly Patterns
Gas optimization should consider Layer 2 execution environments like Optimism and Arbitrum.
Why L2 Matters
Optimized contracts:
Cost less on L1
Perform better on rollups
Scale more efficiently
Best Practices
Avoid heavy calldata
Minimize storage writes
Design for batch execution
Measure, Test, and Continuously Optimize Gas Usage
Gas optimization is not a one-time task — it’s an iterative process.
Recommended Workflow
Write clean, readable code
Profile gas usage
Optimize bottlenecks
Re-test after changes
Tools to Rely On
Foundry gas snapshots
Conclusion
Gas optimization is not optional — it’s essential. It makes your smart contracts cheaper, faster, and more attractive to users. In this guide, we covered:
Top 5 techniques
Minimize storage writes
Favor short-circuit evaluation
Use efficient data types and structures
Leverage view and pure functions
Use constants and immutables
With these tools and practices, you’ll be on the path to writing highly efficient Solidity code.
Ready to Level Up Your Blockchain Career?
FAQs
The biggest cause of high gas fees is excessive storage usage. Operations like writing to storage (SSTORE), updating state variables frequently, and looping over large arrays significantly increase gas costs. Minimizing storage writes and using memory, calldata, or events where possible leads to major gas savings.
Yes — both positively and negatively, depending on implementation. Proper gas optimization improves efficiency without compromising security. However, overly aggressive optimizations (such as removing safety checks or misusing unchecked blocks) can introduce vulnerabilities. Always prioritize correctness and security first, then optimize gas usage carefully.
view and pure functions are free only when called externally (off-chain), such as from a frontend or script. If they are called internally by another function during a transaction, they still consume gas. Marking functions correctly helps the compiler optimize execution and improves clarity.
Layer 2 networks like Optimism and Arbitrum reduce gas costs significantly, but gas optimization still matters. Efficient contracts:
- Cost less when bridged to L1
- Perform better in rollup environments
- Scale more efficiently for high-volume dApps
Well-optimized Solidity code remains valuable across both L1 and L2 ecosystems.
Solidity developers should regularly use:
- Remix IDE Gas Profiler for quick analysis
- Hardhat Gas Reporter or Foundry gas snapshots for automated testing
- Tenderly for deep inspection and real transaction simulations
These tools help validate optimizations and identify gas-heavy operations before deployment.
Yash Singh is the Chief Marketing Officer at Vegavid Technology, a leading AI-driven technology company specializing in AI agents, Generative AI, Blockchain, and intelligent automation solutions. With over a decade of experience in digital transformation and emerging technologies, Yash has played a key role in helping businesses adopt advanced AI solutions that enhance operational efficiency, automate workflows, and deliver personalized customer experiences across industries including fintech, healthcare, gaming, ecommerce, and enterprise technology. An alumnus of Indian Institute of Technology Bombay, Yash combines strong technical expertise with strategic marketing leadership to drive innovation in AI-powered applications, autonomous AI agents, Retrieval-Augmented Generation (RAG), Natural Language Processing (NLP), Large Language Models (LLMs), machine learning systems, conversational AI, and enterprise automation platforms. His expertise spans AI model integration, intelligent workflow automation, prompt engineering, smart data processing, and scalable AI infrastructure development, enabling organizations to accelerate digital transformation and business growth. Passionate about the future of intelligent systems, Yash actively shares insights on AI agents, Generative AI, LLM-powered applications, blockchain ecosystems, and next-generation digital strategies. He is committed to helping businesses embrace AI-first transformation while guiding teams to build impactful, industry-specific solutions that shape the future of innovation and intelligent technology.
















Leave a Reply