74
contract A {
  uint8 a = 0;
}

costs 20150 + 2000 gas during creation.

as compared to

contract A {
  uint a = 0;   // or uint256
}

costing 5050 + 2000 gas during creation

It is odd that a variable that's taking less storage space is costing more gas. Why is that so?

0

5 Answers 5

99

The EVM works with 256bit/32byte words (debatable design decision). Every operation is based on these base units. If your data is smaller, further operations are needed to downscale from 256 bits to 8 bits, hence why you see increased costs.

Btw, if you toggle the "Details" on the online solidity compiler, it will give you the exact assembly dump where the extra opcodes are from. I didn't have time now to interpret them, but if you do and find there's something extra, I'm sure the Solidity team would be happy to add optimizations to work around them.

4
  • 1
    Yeah I saw the assembly instructions. I was going to examine it further if I couldn't get any answers here. Thanks for your reply. It's an odd decision to start with uint256. Next question I wonder if it's then always make sense to just stick to uint256 and never smaller.
    – uzyn
    Commented Apr 16, 2016 at 14:53
  • 13
    @uzyn Using smaller values for storage makes sense, because writing to storage is expensive, and the compiler will pack multiple smaller arguments. For function parameters and memory variables, it only makes sense if you want to restrict the range of values: there's no packing, so it's neither more nor less expensive. Commented Apr 16, 2016 at 15:22
  • 7
    When we create a variable as uint32 inside a struct instead of uint256 and push it into an array it cost much less gas tho.
    – alper
    Commented Feb 2, 2017 at 10:03
  • 1
    @uzyn The EVM uses a word size of 256 bits to facilitate native hashing and elliptic curve operations
    – BonisTech
    Commented Feb 16, 2023 at 10:58
47

It should be noted however, that in a struct, uint8 DOES cost less than a traditional uint, because of the tight packing feature. Also be sure that your uints are next to your other uints, and bytes next to bytes, etc...this further increases the tightly packed features.

2
  • 2
    What do you mean by "be sure that your uints are next to your other uints, and bytes next to bytes, etc...". So in a struct should uints should be defined one after each other on other types as well and why? @VoR0220
    – alper
    Commented Aug 28, 2018 at 12:26
  • 6
    He recommends this because the order you declare your state variables can affect the overall number of storage slots your contract uses. If you declare 2 uint128's and then a uin256, that will use 2 256-bit storage slots; 1 slot for the 2 uint128's and 1 slot for the uint256. If you declare 1 uint128, then a uint256, then a uint128, your contract will use 3 storage slots, because it can't fit the middle uint256 state variable into a storage slot with either of the uint128's, so each variable will need to have its own storage slot.
    – almel
    Commented Apr 25, 2021 at 16:43
19

SOLC 0.4.18: now the difference is small

https://ethfiddle.com/6lt852gx7K

Contract A using uint8 costs 75414 to deploy

Contract B using uint256 costs 73867 to deploy

A difference of 1547 gas.

2
  • 1
    still true in newest solidity versions (same exact costs for 0.6.11 and 0.7.1) Commented Jan 22, 2021 at 19:13
  • 3
    On solidity 0.8.10 is around 100gas more expensive unit8 than uint256 to deploy.
    – imekinox
    Commented Dec 10, 2021 at 0:10
10

Update in December 2021:

If you test something like this: 5 variables instead of just 1, which might be more like a real-world scenario with multiple variables, not just one.

contract A {
  uint8 a = 0;
  uint8 b = 0;
  uint8 c = 0;
  uint8 d = 0;
  uint8 e = 0;
}

Then it's cheaper than its uint256 version.

From remix:

uint8: 69484gas uint256: 78420gas

Update Jun 2022 ( 0.8.15 )

uint8: 83524gas uint256: 90183gas

So you do save on gas using lower size uint, as other comments say if those are arrays you save more.

2

From the docs:

When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.

For more information read the docs about Layout of State Variable in Storage.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.