freecoding.school100% FREE · NO SIGNUP
The EVM CoreISSUE #33 of 48

immutable vs constant · bytecode placement

SoliaVSThe Reentrancy Reaper
Solia saysconstant is a compile-time literal embedded directly in bytecode (zero read cost); immutable is written once in the constructor and baked into runtime bytecode (3 gas to read, no SLOAD).

Both constant and immutable live outside storage, but they differ in when their value is fixed. constant must be a compile-time expression and is inlined wherever it appears — there is no opcode at runtime to "read" it; the value just sits where it would have been used. immutable is set once in the constructor and patched into the runtime bytecode at deploy time; reads use a PUSH-like operation at 3 gas.

Compared to a normal state variable (SLOAD ≈ 2,100 cold), immutable is essentially free and constant is literally free. Use them for fee rates, owner addresses set at deploy, version numbers, etc. The demo compares per-read gas across a million reads.

Power-ups you unlock

The Reentrancy Reaper attacks — common mistakes

Boss battleCompare the gas cost of 1,000,000 reads of a value held as constant, immutable, or a storage variable.

Example code

<!doctype html><html><head><meta charset="utf-8"></head>
<body style="background:#06040d;color:#e6e0ff;font-family:monospace;padding:20px"><pre id="o"></pre>
<script>
const calls = 1000000;
const SLOAD_COLD = 2100, IMMUT = 3, CONST = 0;
const storageCost = calls * SLOAD_COLD;
const immutableCost = calls * IMMUT;
const constantCost = calls * CONST;
document.getElementById('o').textContent = [
  'reads × ' + calls.toLocaleString() + ':',
  '  state variable (SLOAD cold): ' + storageCost.toLocaleString().padStart(13) + ' gas',
  '  immutable (PUSH-like):       ' + immutableCost.toLocaleString().padStart(13) + ' gas',
  '  constant (inlined literal):  ' + constantCost.toLocaleString().padStart(13) + ' gas',
  '',
  'savings vs storage: ',
  '  immutable: ' + (storageCost - immutableCost).toLocaleString() + ' gas (~' + Math.round(100*(storageCost-immutableCost)/storageCost) + '%)',
  '  constant : ' + (storageCost - constantCost).toLocaleString() + ' gas (100%)',
  '',
  'constant must be a compile-time expression; immutable can be set in the constructor'
].join('\n');
</script></body></html>
▶ Open the interactive comic issue
‹ Storage Layout · Slots · Mappings · ArraysThe Optimizer · Runs · Via-Ir Pipeline ›