RFC 4122/9562: UUID version 7 and 8 implementation

In light of the following comment on issue 89083, I am considering to switch to Method 1, §6.2 which is a Fixed Bit-Length Dedicated Counter. This would be quite distinct from Method 2 that I suggested but the rationale would be that it’s closer to what other implementations do.

In the end, I don’t want Python to have another method for generating UUIDs compared to other libraries. However, I missed the fact that the Rust implementation is actually a massively used library https://crates.io/crates/uuid/reverse_dependencies. In particular, I believe that their implementation would serve as a reference and thus I will go for a similar implementation of that library.

In addition, due to the fact that UUIDv7 are likely to be used for database storage, improving over UUIDv6, supporting timestamp offsets could be considered (see this discussion).

In summary, here’s what I would suggest for UUIDv7:

# --- 48 ---   -- 4 --   --- 12 ---   -- 2 --   --- 30 ---   - 32 -
# unix_ts_ms | version | counter_hi | variant | counter_lo | random
  • The counter (split into counter_hi and counter_lo) is initialized to a random 42-bit integer with MSB set to 0 (so it’s effectively a 41-bit random integer). Whenever a new UUIDv7 is generated within the same millisecond, the counter is incremented by 1.
  • If the counter overflows, we increment the timestamp and reset the counter to a random 42-bit integer with MSB set to 0.
  • The random part is always re-generated, independently of whether the counter was incremented or not.

The rationale of having the MSB set to 0 is given at the end of the paragraph Fixed Bit-Length Dedicated Counter Seeding:

For example, a 24-bit counter could have the 23 bits in least significant, rightmost position randomly initialized. The remaining most significant, leftmost counter bit is initialized as zero for the sole purpose of guarding against counter rollovers.

1 Like