I try to specify uint type to uint16 instead of just doing uint or uint256 when dealing with time stamps but it says that I must use at least uint24. It works with uint24, but shouldn't uint16 be plenty enough?

3 Answers 3


Not really an answer to what you're asking, but...

Decreasing the size of a uint to less that 256 bits will increase the associated gas costs, not decrease it like you might be expecting. It'll be best to leave it as a uint256.

See: Why does uint8 cost more gas than uint256?


Noting that timestamps are the number of seconds since the Unix epoch:

  • uint16 maximum value = 65536 -> 01/01/1970 @ 6:12pm (UTC)
  • uint24 maximum value = 16777216 -> 07/14/1970 @ 4:20am (UTC)

So these values are too small.

Calling block.timestamp (or now) currently returns 1508618011, which is 0b1011001111010111010111100011011. This requires 31 bits. So you're looking at least at a uint32, but more if you want to be future-proof.

  • What if we were talking about something that would be saved to storage? I assume it would be best practices to forexample use uint8 instead of uint256 for decimals, saving gas costs too.
    – NowsyMe
    Commented Oct 21, 2017 at 20:17
  • Yep, true for variables written to storage - writing smaller quantities is cheaper. You'll want to experiment depending on how you're using the timestamps. Commented Oct 21, 2017 at 20:31
  • Storage is written in blocks of 32 bytes. Using smaller values is not cheaper Commented Oct 21, 2017 at 20:45
  • 5
    uint32 is more than enough, in my opinion: 2^32 - 1 equals to 4294967295, i.e. Sun Feb 07 2106. None of us will probably be alive at that time, and I highly doubt Solidity will still be used to write distributed applications :)
    – skozin
    Commented Nov 23, 2017 at 2:42
  • 1
    When storing in a struct, they are lined up on 32 byte blocks, so you can fit multiple uint32s in a struct and save on storage costs big time...
    – Kevin
    Commented Mar 13, 2019 at 20:12

According to Solidity docs block.timestamp is a uint which is an alias for unit256

block.timestamp (uint): current block timestamp

So I personally will use the same in case Solidity still around in Year 33658 :)



Other answers aren't helping to clearly assess when to use the default uint256 or a smaller uintN. I'll give it a try.

There are two parts:

Can your code benefit from tight packing?

(Tested with solc 0.8.15)

Tight packing provides clear gains (gas savings) if your code is regularly writing the tightly packed variables to storage together. For example:

contract A {
    uint128 tightPacked1;
    uint128 tightPacked2;

    function writeBoth(uint128 tp1, uint128 tp2) public {
        tightPacked1 = tp1;
        tightPacked2 = tp2;

But if your code isn't writing these variables together, there are no gains from tight packing. More, there are even losses compared to the uint256 version because of downscaling as mentioned by Richard Horrocks (observed approx 2100 gas usage increase per write for non-0 numbers). For example:

contract A {
    uint128 tightPacked1;
    uint128 tightPacked2;

    function write1(uint128 tp1) public {
        tightPacked1 = tp1;

    function write2(uint128 tp1) public {
        tightPacked2 = tp2;

Last, if doing very few writes to storage (for example only in the contract constructor), you have to compare tight packing saving with increased costs due to notably downscaling.

In any case, use a tool to test gas costs of your functions in different scenarios.

Which uintN to use

If tight packing is a good idea, you can look into picking the smallest uintN that does the job.

For a timestamp, uint32 can be enough (2106 max). But for time durations, you can go much lower (for example uint24 can do 6 months).

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.