Packing Variables by EVM

Published by Mario Oettler on

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.

DeploymentFirst value assignmentSecond value assignment
Unpacked42091665676867
Packed42091447174917

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.

TotalExecutionTransaction
Read varA (packed)27117251623580
Read varC (packed)27021243223496
Read varB (unpacked)27151254523609

Categories: