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

Python
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:

Python
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:

Python
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:

Python
# 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