UUID7 is a type of time-ordered UUID, which compared to UUID4:
- Does not degrade performance when used as primary keys in databases (e.g. this benchmark).
- Includes its creation timestamp, which makes
created_at
-like columns redundant.
Note that when used as (external) IDs, UUID7 leak the object creation time. Regardless ofwhether or not this is actually a security risk, I'm wondering if the following scheme can be used to discard timestamp information (loosing time-sortability), while preserving database performance:
- Generate a secret UUID4.
- When inserting a new object, generate a new UUID7, and bitwise-xor it with the secret UUID.
- Use the result as the object's ID (and primary key)
Sample Python code:
>>> from uuid import uuid4, UUID>>> from uuid_extensions import uuid7, uuid_to_datetime>>> def obfuscate(u1: UUID, u2: UUID) -> UUID: return UUID(bytes=bytes(a ^ b for a, b in zip(u1.bytes, u2.bytes)))>>> secret = uuid4()>>> u1 = uuid7()>>> u2 = uuid7()>>> id1 = obfuscate(u1, secret)>>> id2 = obfuscate(u2, secret)>>> print(f'\n secrete= {secret}\n u1 = {u1} --> id1 = {id1}\n u2 = {u2} --> id2 = {id2}') secret = 1bc9e84c-c8d6-47c0-afd3-b78a4333f4bc u1 = 06732e7b-9aad-7e72-8000-6978adc183a5 --> id1 = 1dbac637-527b-39b2-2fd3-def2eef27719 u2 = 06732473-1b2b-7d9a-8000-f7261455e941 --> id2 = 1dbacc3f-d3fd-3a5a-2fd3-40ac57661dfd>>> uuid_to_datetime(u1)datetime.datetime(2024, 11, 12, 5, 29, 29, 667457, tzinfo=datetime.timezone.utc)>>> uuid_to_datetime(id1) is NoneTrue