UUID generator · Guide
UUID v7 Python: Time-Ordered UUIDs in Python
Python's `uuid` module covered versions 1, 3, 4 and 5 for two decades. v7 arrived in Python 3.14; before that a package or a dozen lines of your own fills the gap.
Python 3.14 and later
import uuid
uuid.uuid7() # standard library, Python 3.14+On older versions the uuid6 package provides uuid6.uuid7() with the same output format, so switching later is a one-line change.
Writing it yourself
The layout is a 48-bit millisecond timestamp, the version nibble, 12 random bits, the variant bits, then 62 more random bits:
import os, time, uuid
def uuid7() -> uuid.UUID:
ms = int(time.time() * 1000)
rand = os.urandom(10)
b = bytearray(ms.to_bytes(6, "big") + rand)
b[6] = (b[6] & 0x0F) | 0x70 # version 7
b[8] = (b[8] & 0x3F) | 0x80 # RFC 9562 variant
return uuid.UUID(bytes=bytes(b))The two bit operations are what make it a valid UUID rather than 128 random-ish bits. This version does not guarantee ordering within a single millisecond — the libraries add a counter for that.
Reading the timestamp back
The first six bytes are the creation time, which is occasionally useful for debugging and is also the privacy caveat:
from datetime import datetime, timezone
def created_at(u: uuid.UUID) -> datetime:
ms = int.from_bytes(u.bytes[:6], "big")
return datetime.fromtimestamp(ms / 1000, tz=timezone.utc)With Django and SQLAlchemy
Both support a native UUID column, so pass the callable as the default and let the database store 16 bytes:
# Django
id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
# SQLAlchemy
id = mapped_column(Uuid, primary_key=True, default=uuid7)Pass the function, not uuid7() — calling it in the field definition evaluates once at import and gives every row the same id, which is a classic Django mistake.
Frequently asked questions
Is uuid7 in the Python standard library?
Yes, from Python 3.14. Use the uuid6 package on earlier versions.
Can I extract the creation time?
Yes — the first 48 bits are the Unix millisecond timestamp.
Why does every row get the same UUID in Django?
The default was called instead of passed. Use default=uuid7, not default=uuid7().
Ready to try it?
Open the free browser-based UUID generator and apply what you just read — no sign-up, runs locally.
Open the UUID generator tool