Python UUID: Generate Unique IDs with uuid1 and uuid4
Generate a Python UUID with the built-in uuid module. Code examples for uuid1, uuid4, and uuid5, a comparison table, and best practices for unique IDs.
Python UUID: How to Generate Unique IDs with uuid1 and uuid4
To generate a Python UUID, import the built-in uuid module and call one of its functions — most commonly uuid.uuid4() for a random identifier or uuid.uuid1() for a time-and-machine-based one. A UUID (Universally Unique Identifier) is a 128-bit value that is practically guaranteed to be unique, which makes it ideal for database keys, file names, and request tracing. No external library is needed; the module ships with Python.
This guide explains what UUIDs are, walks through every common generation method with copy-ready code, and shows when to choose uuid4 versus uuid1. By the end you will know how to produce, format, and validate UUIDs confidently. If you just need a UUID right now without writing code, our free online UUID generator creates valid identifiers instantly in your browser — no signup, no install.
What Is a UUID?
A UUID is a 128-bit number, usually written as 32 hexadecimal digits in five groups separated by hyphens, like 550e8400-e29b-41d4-a716-446655440000. The format is standardized as 8-4-4-4-12 characters. The point of a UUID is to be unique without any central authority handing out values: two programs on opposite sides of the world can each generate a UUID and the odds of a collision are vanishingly small.
This independence is why UUIDs are everywhere in modern software. They serve as primary keys in distributed databases, unique file or upload names, session and transaction identifiers, and correlation IDs for tracing a request across microservices. Because each service can mint its own IDs offline, there is no bottleneck or coordination needed.
The UUID Versions You Will Actually Use
The UUID standard defines several versions. In Python, three are commonly used:
- uuid4 — random. Generated from cryptographically strong random numbers. This is the default choice for most applications because it leaks no information and is simple.
- uuid1 — time-based. Built from the current timestamp and the computer's MAC address. It is sortable by creation time but can expose the machine's network address.
- uuid3 and uuid5 — name-based. Generated by hashing a namespace plus a name (uuid3 uses MD5, uuid5 uses SHA-1). The same input always produces the same UUID, which is useful for deterministic IDs.
Generating a Python UUID with uuid4 (Random)
The most common way to create a Python UUID is uuid4(). It returns a random identifier and requires no arguments:
import uuid
my_id = uuid.uuid4()
print(my_id) # e.g. 3f2504e0-4f89-41d3-9a0c-0305e82c3301
The object returned is a UUID instance, not a string. To get a plain string for storage or display, wrap it in str():
id_string = str(uuid.uuid4())
Because uuid4 draws on the operating system's random source, the chance of generating the same UUID twice is so small it can be ignored for practical purposes. This makes it the safe default when you do not need IDs to be sortable or reproducible.
Generating a Python UUID with uuid1 (Time-Based)
If you want IDs that encode their creation time, use uuid1(). It combines the current timestamp with the host's MAC address:
import uuid
time_id = uuid.uuid1()
print(time_id) # contains a timestamp and node identifier
The trade-off is privacy: because uuid1 includes the MAC address, it can reveal which machine generated the ID. If that matters, prefer uuid4. You can also pass optional node and clock_seq arguments to override the MAC address, but most code simply calls it with no arguments.
Name-Based UUIDs with uuid5
When you need the same input to always produce the same UUID, use uuid5() (or the older uuid3()). You supply a namespace and a name string:
import uuid
uid = uuid.uuid5(uuid.NAMESPACE_DNS, "example.com")
print(uid) # always the same for "example.com"
This determinism is handy when you want a stable ID derived from an existing unique value, such as a URL or username, without storing a separate lookup.
Comparing the UUID Methods
The table below summarizes the practical differences so you can pick the right function for your use case.
| Method | Based on | Sortable by time? | Deterministic? | Best for |
|---|---|---|---|---|
| uuid4() | Random data | No | No | General-purpose unique IDs (default) |
| uuid1() | Timestamp + MAC | Yes | No | IDs where creation order matters |
| uuid5() | Namespace + name (SHA-1) | No | Yes | Reproducible IDs from a known value |
| uuid3() | Namespace + name (MD5) | No | Yes | Legacy deterministic IDs |
Rule of thumb: reach for uuid4 unless you have a specific reason to need time ordering (uuid1) or reproducibility (uuid5). When in doubt, uuid4 is the safe, private default.
Worked Example: A Unique Filename and Database Key
Here is a small, realistic snippet that uses a UUID to build a collision-free filename and a record ID:
import uuid
record_id = str(uuid.uuid4())
filename = f"upload_{uuid.uuid4().hex}.png"
print(record_id) # 7c9e6679-7425-40de-944b-e07fc1f90ae7
print(filename) # upload_7c9e667974254...90ae7.png
Two useful attributes appear here. The .hex attribute returns the 32-character UUID with no hyphens, which is convenient for filenames and URLs. You can also access .int for the full integer value or .bytes for the raw 16-byte form. To turn a stored string back into a UUID object, pass it to the constructor: uuid.UUID("7c9e6679-7425-40de-944b-e07fc1f90ae7"). This also validates the string and raises an error if it is malformed.
Working with UUID Attributes and Formats
A Python UUID object is richer than a plain string. Once you have one, several attributes let you reshape it for different contexts without regenerating anything:
str(u)— the standard hyphenated form, e.g.550e8400-e29b-41d4-a716-446655440000.u.hex— 32 hex characters with no hyphens, ideal for filenames, URLs, or tokens.u.int— the full 128-bit value as a Python integer.u.bytes— the raw 16-byte big-endian representation, useful for compact binary storage.u.version— the version number (1, 3, 4, or 5), handy for verifying which generator produced an ID.
Going the other way is just as easy. The uuid.UUID constructor accepts any of these forms. You can rebuild a UUID from a hyphenated string with uuid.UUID("550e8400-e29b-41d4-a716-446655440000"), from a hex string with uuid.UUID(hex="550e8400e29b41d4a716446655440000"), or from an integer with uuid.UUID(int=some_number). This flexibility means you can store a UUID in whatever format your system prefers and reconstruct the object later without losing information.
UUIDs in Databases and APIs
One of the most common reasons to generate a Python UUID is to use it as a database primary key. UUIDs let your application assign an ID before the row is ever inserted, which simplifies code and avoids a round trip to fetch an auto-incremented integer. They also prevent the predictable, guessable IDs that sequential integers create — a small but real security benefit for public-facing APIs, where exposing /users/1, /users/2, and so on invites scraping.
That said, random UUIDs do have a cost: because they are not ordered, inserting them as a clustered index key can fragment the index and slow down very large tables. If you are operating at that scale and need both uniqueness and insertion order, look at time-ordered variants (such as UUID version 7, available in newer tooling) or store a separate timestamp column. For the vast majority of applications, plain uuid4 is more than fast enough.
Common Questions and Best Practices
A few practical tips keep UUID usage clean:
- Store as strings or native UUID types. Many databases (such as PostgreSQL) have a dedicated UUID column type that is more efficient than storing the text.
- Do not rely on uuid4 for ordering. Random UUIDs have no chronological order; add a separate timestamp column if you need to sort by creation time.
- Validate untrusted input. Wrap incoming ID strings in
uuid.UUID(value)inside a try/except to reject malformed values early. - Prefer uuid4 for anything user-facing. It avoids exposing the MAC address that uuid1 embeds.
If you only need a handful of IDs for testing, configuration, or a quick script, generating them by hand in code is overkill. Our free UUID generator produces valid version-4 UUIDs in one click, so you can copy and paste without opening a Python shell.
Related Reading
Find more developer guides in our Developer Tools hub. These cover everyday tasks like formatting, encoding, and generating identifiers, all with free browser-based tools that require no setup. Bookmark the hub for quick access whenever you need a fast, reliable utility during development.
Frequently Asked Questions
How do I generate a UUID in Python?
Import the built-in uuid module and call a generator function. The most common is uuid.uuid4() for a random ID. Wrap it in str() if you need a plain string. No external package is required.
What is the difference between uuid1 and uuid4 in Python?
uuid1 is time-based and built from the current timestamp plus the machine's MAC address, so it is sortable but can expose hardware info. uuid4 is fully random, leaks no information, and is the recommended default for most uses.
Is uuid4 truly unique?
Not mathematically guaranteed, but the probability of a collision is so astronomically small that it is treated as effectively unique. You would need to generate billions of UUIDs before a duplicate became realistically likely.
Do I need to install anything to use UUIDs in Python?
No. The uuid module is part of the Python standard library, so it is available in every standard Python installation with a simple import uuid.
How do I convert a UUID to a string?
Pass the UUID object to str(), as in str(uuid.uuid4()). For a version without hyphens, use the .hex attribute. To rebuild a UUID object from a string, use uuid.UUID(value).
Which UUID version should I use?
Use uuid4 by default. Choose uuid1 only when you need IDs ordered by creation time, and uuid5 when you need the same input to always produce the same UUID. Avoid uuid3 except for legacy compatibility.
Can I validate a UUID string in Python?
Yes. Pass the string to uuid.UUID(value) inside a try/except block. If the string is not a valid UUID, it raises a ValueError, which lets you reject bad input cleanly.