`storage` is the contract's persistent state and by far the most expensive. `memory` is a scratch area wiped after the call. `calldata` is the read-only, non-modifiable input of the transaction and the cheapest place to read arguments from.
function sum(uint256[] calldata xs) external pure returns (uint256 t) {
for (uint256 i; i < xs.length; ++i) t += xs[i];
}
function touch() external {
Stake storage s = stakes[msg.sender]; // reference — writes persist
Stake memory copy = stakes[msg.sender]; // copy — writes are discarded
}A `storage` reference writes through to state; a `memory` copy does not.