Packing Variables by EVM
Last Updated on 24. March 2025 by Mario Oettler
The (Ethereum Virtual Machine) EVM reserves slots for each state variable. Each slot is 32 bytes (256 bits) in size. However, it is possible to store multiple variables in a single slot, as long as they are not larger than 32 bytes in total. This is called memory packing. Such tightly packed variables can have a significant impact on the cost of gas during the operation of a smart contract. If we have four variables, each 32 bytes (or 256 bits) long, we need four slots, as shown in the figure below.

If we have four variables, each 8 bytes (or 64 bits) long, we can pack them into one single slot.

To pack two or more storage variables into one slot, you have to declare them one after the other.
Example
The following example illustrates the difference:
Unpacked
uint64 varA
uint256 varB;
uint128 varC;
Here, three slots are assigned.
pragma solidity 0.8.29;
contract Unpacked{
uint64 varA;
uint256 varB;
uint128 varC;
function setVariables() public{
varA = 1;
varB = 1;
varC = 1;
}
}
Packed
uint64 varA
uint128 varC
uint256 varB
pragma solidity 0.8.29;
contract Packed{
uint64 varA;
uint128 varC;
uint256 varB;
function setVariables() public{
varA = 1;
varB = 1;
varC = 1;
}
}
Here, varA and varC are stored in a single slot because they don’t exceed the size of 256 bits (or 32 bytes). varB doesn’t fit in this slot anymore. So another slot is allocated to it. In total we need two slots. Compared to the unpacked example, we save one slot.
This packing is done automatically by the EVM. We just need to declare the variables in the right order.
Here is the comparison of the gas consumption.
Deployment | First value assignment | Second value assignment | |
Unpacked | 42091 | 66567 | 6867 |
Packed | 42091 | 44717 | 4917 |
We can see that packing doesn’t affect the deployment cost (unless the values are assigned during deployment). Instead, it affects the first value assignment (from zero to 1) and the second value assignment (from 1 to 1).
Packing, however, affects the costs of reading a variable. Reading a packed value is slightly more expensive than reading a non-packed value.
Total | Execution | Transaction | |
Read varA (packed) | 27117 | 2516 | 23580 |
Read varC (packed) | 27021 | 2432 | 23496 |
Read varB (unpacked) | 27151 | 2545 | 23609 |