New time-based UUID formats which are suited for use as a database key.
This module extends immutable UUID objects (the UUID class) with the functions uuid6()
, uuid7()
, and uuid8()
from the IETF draft.
pip install uuid6
from uuid6 import uuid6, uuid7, uuid8
my_uuid = uuid6()
print(my_uuid)
assert my_uuid < uuid6()
my_uuid = uuid7()
print(my_uuid)
assert my_uuid < uuid7()
my_uuid = uuid8()
print(my_uuid)
assert my_uuid < uuid8()
Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible.
UUID version 7 features a time-ordered value field derived from the widely implemented and well known Unix Epoch timestamp source, the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded. As well as improved entropy characteristics over versions 1 or 6.
If your use case requires greater granularity than UUID vesion 7 can provide, you might consider UUID version 8. UUID version 8 doesn't provide as good entropy characteristics as UUID version 7, but it utilizes timestamp with nanosecond level of precision.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time_high |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time_mid | time_low_and_version |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|clk_seq_hi_res | clk_seq_low | node (0-1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| node (2-5) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unix_ts_ms |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unix_ts_ms | ver | rand_a |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|var| rand_b |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| rand_b |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unix_ts_ms |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unix_ts_ms | ver | subsec_a |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|var| subsec_b | rand |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| rand |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
unix_ts_ms
: 48 bit big-endian unsigned number of Unix epoch timestamp with millisecond level of precisionver
: The 4 bit UUIDv8 version (1000)subsec_a
: 12 bits allocated to sub-second precision valuesvar
: 2 bit UUID variant (10)subsec_b
: 8 bits allocated to sub-second precision valuesrand
: The remaining 54 bits are filled with cryptographically strong random data
20 extra bits dedicated to sub-second precision provide nanosecond resolution. The unix_ts_ms
, subsec_a
, and subsec_b
fields guarantee the order of UUIDs generated within the same nanosecond by monotonically incrementing the timer.
Run the shell script bench.sh to test on your own machine.
MacBook Air 2020
Python 3.10.4
Mean +- std dev: 870 ns +- 11 ns
Mean +- std dev: 1.17 us +- 0.01 us
Mean +- std dev: 2.18 us +- 0.02 us
Mean +- std dev: 1.60 us +- 0.02 us
Mean +- std dev: 1.78 us +- 0.02 us
+-----------+--------+-----------------------+-----------------------+-----------------------+-----------------------+
| Benchmark | uuid1 | uuid4 | uuid6 | uuid7 | uuid8 |
+===========+========+=======================+=======================+=======================+=======================+
| timeit | 870 ns | 1.17 us: 1.35x slower | 2.18 us: 2.51x slower | 1.60 us: 1.84x slower | 1.78 us: 2.04x slower |
+-----------+--------+-----------------------+-----------------------+-----------------------+-----------------------+