javascriptuuid

How long would it take to exhaust integers up to MAX_SAFE_INTEGER?


I found that searching for this answer confusing and not well documented.

In JavaScript you have a MAX_SAFE_INTEGER defined as 2^53 - 1

I did discover an article that put such large numbers into perspective however they focus on 2^64. And JS uses a smaller number. Most birthday paradox calculators lack the ability to scale to that number.

Why is this interesting? I found myself debating with developers about the use of a UUID(v4) for unique IDs in their web apps. By comparison a monotonic counter globally used in a single web app would have an entire 2^53 - 1 space of unique values per tab session. I'm interested in understanding the trade off of the exhaustion of values for a monotonic counter compared to the collision probability of UUIDv4.

Adding Context

This thought experiment came about from an exercise in generating unique IDs for a web application. The intent of these unique IDs was so components within the app when mounted/rendered could have a unique ID for that instance that they could then use in things like <label for=…> and <input id=…>.

Much of the assumptions for the team when they needed a unique ID they would generate a Version 4 (random) UUID.

Since these were to guarantee uniqueness it got me thinking that perhaps instead of relying on the improbable nature of finding a collision in the UUID space within our lifetimes to guarantee uniqueness that instead a form of a monotonic counter (clock) would be far easier to have the same guarantees.

const uniqueId = ((id) => () => ++id)(0);

This lead me to wonder what the worst case scenario was for a web application to exhaust the MAX_SAFE_INTEGER space of values. And to compare it to the UUID space exhaustion and possible collision (birthday paradox).

And lastly why use randomness (however large the space is) instead of a monotonic counter for uniqueness in this scenario.


Solution

  • The calculation to find the time to exhaust MAX_SAFE_INTEGER (in years) should be pretty straightforward if we assume we're working with a monotonic counter that increments once per second.

    1. Calculate MAX_SAFE_INTEGER (2^53 - 1) = 9,007,199,254,740,991
    2. Divide that by the number of seconds in a year (this only works assuming the counter increments once per second), which would be ~31,536,000 seconds. So, 9,007,199,254,740,991 / 31,536,000 = 285,616,414.7 years to exhaust.