Track 3 · Ethereum & the EVM · lesson 5

Storage, memory, calldata

10 min


Three places data can live inside a contract, priced so differently that the choice shapes how Solidity is written.

calldata16 / byteread-only, cheapestmemory3 / wordscratch space, wiped after the callstorage22,100 / slotpermanent, every node keeps it
Bars to scale. Storage is not slightly more expensive — it is thousands of times more.

What each one is

storage — the contract's permanent state. Survives between transactions. Every node keeps it, indefinitely, which is why a fresh slot costs 22,100 gas.

memory — a scratch pad for the duration of one call. Wiped the moment the call returns. A few gas per word.

calldata — the raw, read-only bytes of the incoming call. Cannot be modified, and costs nothing to keep, because it was already paid for as part of the transaction's data.

The bar chart is to scale. Storage is not somewhat more expensive than memory — it is roughly seven thousand times more expensive.

That single ratio explains most of what looks like odd style in production Solidity. Values cached in locals, loops rewritten to touch state once, structs packed into single slots: all of it is people avoiding that bar.

Why Solidity makes you say which

For value types like uint256 and address, Solidity knows. For arrays, structs, strings and bytes it demands you state the location:

function process(uint256[] calldata input) external {
    uint256[] memory working = new uint256[](input.length);
    ...
}

Leave it out and you get Data location must be "storage", "memory" or "calldata" — one of the first errors every Solidity developer meets.

Predict

A function takes a large array it only reads. Should the parameter be `memory` or `calldata`?

Choose one answer

The assignment trap

This one bites everyone once:

Task storage t = tasks[0];   // a reference — changes persist
Task memory t2 = tasks[0];   // a copy — changes are discarded

storage gives you a pointer into state. memory gives you a snapshot. Modify the snapshot, and your change vanishes when the function returns, silently and with no warning.

Check

You copy a struct out of storage with `memory`, change a field, and the function ends. What happened on-chain?

Choose one answer

Worth remembering

  • storage is permanent and ~7,000× more expensive than memory; memory is per-call scratch; calldata is read-only incoming bytes.
  • Solidity requires an explicit location for arrays, structs, strings and bytes.
  • Read-only external parameters should be `calldata` to avoid a copy.
  • A `storage` local is a reference; a `memory` local is a copy.
  • Modifying a memory copy and expecting it to persist is a silent, common bug.