🏠 Home
Beginner
01 — Introduction to Solidity 02 — Setting Up Your Environment 03 — Your First Smart Contract 04 — Data Types & Variables 05 — Functions & Visibility 06 — Control Flow 07 — Arrays & Mappings 08 — Structs & Enums
Intermediate
09 — Events & Logging 10 — Modifiers 11 — Inheritance 12 — Interfaces & Abstract Contracts 13 — Error Handling 14 — Ether & Wei 15 — Payable Functions 16 — msg.sender & msg.value 17 — Storage vs Memory vs Stack
Advanced
18 — Gas Optimization 19 — ERC-20 Tokens 20 — ERC-721 NFT Standard 21 — Contract Security 22 — Reentrancy Attacks 23 — Oracles & Chainlink 24 — Upgradeable Contracts 25 — Deploying to Mainnet
SolidityMaster / Lesson 17
Lesson 17 of 25

Storage vs Memory vs Stack

Understand EVM data locations and how they affect gas costs.

Intermediate

The Three Data Locations

Every variable in Solidity has a data location. Understanding this is critical for both correctness and gas efficiency.
  • storage — persistent, on-chain. Expensive (20,000 gas to write a new slot).
  • memory — temporary, in-function. Cheap, erased after the call.
  • stack — for simple value types inside functions. Very cheap, limited to 1024 slots.
  • calldata — immutable external function parameter data. Cheapest for read-only params.
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract DataLocations {
    uint256[] public storageArr; // lives in storage

    function work(uint256[] calldata input) external {
        // calldata: read-only external param (cheapest)

        uint256[] memory memArr = new uint256[](input.length);
        // memory: temp array, erased after this function ends

        for (uint i = 0; i < input.length; i++) {
            memArr[i] = input[i] * 2;
        }

        // Push to storage — the only way to persist changes
        for (uint i = 0; i < memArr.length; i++) {
            storageArr.push(memArr[i]);
        }
    }
}

Storage References vs Copies

When you assign a storage struct to a local variable, you get a reference (pointer). Modifications affect the original. To make a copy, use memory.
Solidity
struct Item { uint256 price; bool available; }
Item[] public items;

function updatePrice(uint256 idx, uint256 newPrice) public {
    // Storage reference — modifies items[idx] directly
    Item storage item = items[idx];
    item.price = newPrice;        // ✅ persists on-chain
}

function readItem(uint256 idx) public view returns (Item memory) {
    // Memory copy — safe read-only snapshot
    Item memory copy = items[idx];
    copy.price = 999;  // changes copy only, not storage
    return copy;
}

Gas Cost Comparison

Understanding gas costs for data locations helps you optimize contracts dramatically.
Solidity
// Gas costs (approximate, EIP-2929):
//
// SSTORE new slot:      ~20,000 gas  ← very expensive
// SSTORE update slot:   ~5,000 gas
// SLOAD cold slot:      ~2,100 gas
// SLOAD warm slot:      ~100 gas
// MSTORE (memory):      ~3 gas
// Stack operation:      ~3 gas

// Optimization pattern: cache storage in memory
function sumStorageArray() public view returns (uint256 sum) {
    uint256[] memory arr = storageArr; // cache in memory once
    for (uint i = 0; i < arr.length; i++) {
        sum += arr[i]; // reads from memory, not storage
    }
}