Generating UUIDs in Python: uuid4, uuid7 and the uuid module
You do not need a third-party package to generate a UUID in Python: the standard-library uuid module does it in two lines. import uuid and uuid.uuid4() return a random UUID on any Python you are likely to run. On Python 3.14 or newer, uuid.uuid7() adds time-ordered IDs that keep database indexes fast. This page walks through the quick start, the version picker, input validation, bulk generation, and the storage habits that decide whether UUIDs stay fast in production.
The quick start
uuid4() is the default choice for IDs of users, rows, requests and objects: 122 random bits from the operating system's secure random source, with no timestamp and no machine identifier in the value. uuid7() is the newer alternative: a millisecond timestamp followed by counter and random bits, so values sort by creation time instead of scattering across the index.
import uuid
uid = uuid.uuid4()
print(uid) # different on every call
The v7 variant is the same shape:
import uuid
uid = uuid.uuid7() # Python 3.14+
uuid7() landed in the standard library with Python 3.14. On older interpreters it is not built in; the options are a backport such as uuid-utils (install with pip install uuid-utils) or uuid4() plus a timestamp column of your own. Why time-sorting matters, and how v7 differs from the older versions, is the subject of our UUIDv7 guide; the full version comparison covers every version side by side.
Which version to pick
| Call | Version | Built from | Typical use |
|---|---|---|---|
uuid.uuid4() | 4 | 122 random bits from a secure random source | the default: users, rows, requests, objects |
uuid.uuid7() | 7 | millisecond timestamp, counter, random bits; sorts by time (Python 3.14+) | database keys, event logs, fast writers |
uuid.uuid1() | 1 | host identifier (the MAC address when available) + timestamp | legacy interop; leaks the machine, so think twice |
uuid.uuid3(namespace, name) | 3 | MD5 hash of a name inside a namespace | derived IDs: same name in, same UUID out |
uuid.uuid5(namespace, name) | 5 | SHA-1 hash of a name inside a namespace | same idea as v3 with the stronger hash; the usual pick |
In doubt, take uuid4(). Take uuid7() when rows arrive faster than readers do, because nearly sorted keys land next to each other in the index instead of splitting every page. The deterministic pair uuid3() and uuid5() answers a different question: give them the same namespace and the same name and they return the same UUID every time, which is how you map an email address or a domain to a stable identifier. Python 3.14 also ships uuid6() (the time-sorting idea applied to the older v1 layout) and uuid8().
Validate a UUID from user input
Values that arrive from forms, APIs or URL parameters fail on their own schedule. uuid.UUID(string) raises ValueError on anything it cannot parse, which makes the try/except the whole pattern:
import uuid
def parse_uuid(value):
try:
return uuid.UUID(value)
except ValueError:
return None
uid = parse_uuid("not-a-uuid") # None
The constructor accepts more than the canonical form: the hyphenated form, plain 32-character hex, braced form and the urn:uuid: prefix all parse, and comparing UUID objects ignores case, so ABCDEF00-... and abcdef00-... are the same value. Parse once and compare objects, and the spelling of the input stops mattering.
Bulk generation and the four output formats
A list comprehension covers volume:
ids = [uuid.uuid4() for _ in range(1000)]
Each UUID object renders in four formats, and each has a home:
str(uid): the canonical hyphenated form, 36 characters, for display and URLsuid.hex: the same value as 32 characters, no hyphens, for compact text columnsuid.bytes: the 16 raw bytes, ready for binary columnsuid.urn: theurn:uuid:form defined in RFC 9562, for documents that expect it
Since Python 3.12 the module also runs from the command line: python -m uuid -u uuid4 prints one fresh ID, and python -m uuid -u uuid7 works from 3.14.
Need a handful of IDs right now, without writing a script? The UUID Generator makes v4 and v7 IDs in bulk, straight in your browser.
The UUID Generator runs entirely in your browser, so the IDs you generate never leave your machine.
Three storage habits that slow UUIDs down
- Storing strings where a native type exists. Postgres has a native uuid column type that stores 16 bytes and compares integers. MySQL 8.0 ships UUID_TO_BIN() for the same move: BINARY(16) in the table, the 36-character form only at the edges of your system. Keeping every ID as CHAR(36) more than doubles the size of each stored value and every index entry.
- Regenerating instead of persisting. Generate the ID once, when the object is created, and store it with everything that references it. Calling uuid4() again on the way out breaks every join and every history that pointed at the old value. uuid5() is the deliberate exception: the same namespace and name always return the same UUID.
- Comparing formatted strings. ABCDEF00-... and abcdef00-... are equal as UUIDs but different as strings. Parse both sides with uuid.UUID() and compare the objects, or normalize through .hex, and letter case stops mattering.
Frequently Asked Questions
How do I generate a UUID in Python?
Import the uuid module and call uuid.uuid4(): it returns a random UUID object, and str() on it gives the familiar 36-character form. That is the standard choice for IDs of users, rows and requests. On Python 3.14 or newer, uuid.uuid7() returns a time-ordered UUID that sorts by creation time, which keeps database indexes fast.
Does Python have a built-in UUID generator?
Yes. The uuid module is part of the standard library, so nothing needs installing: import uuid and call uuid.uuid4() for a random UUID. The module also provides uuid1(), uuid3() and uuid5(), uuid7() from Python 3.14, and a command-line interface (python -m uuid) since Python 3.12.
How do I generate UUID v7 in Python?
Call uuid.uuid7(). It is in the standard library from Python 3.14 onward and returns time-ordered UUIDs per RFC 9562, which keep database indexes fast on high-write tables. On Python 3.13 and older the function is not built in; install a backport such as uuid-utils from PyPI (pip install uuid-utils), or use uuid4() and store the creation timestamp in its own column.