UUID Generator: Create v1, v3, v4, and v5 UUIDs
Learn when to use UUID versions 1, 3, 4, and 5, and generate them with runnable code. Includes canonicalization, security, troubleshooting, and database tradeoffs.

Choose UUIDv4 for a new, independent identifier; choose UUIDv3 or UUIDv5 when the same namespace and canonical name must always produce the same identifier; use UUIDv1 only when its time-based construction fits and its metadata exposure is acceptable. UUIDv3 uses MD5, UUIDv5 uses SHA-1, and UUIDv4 uses random or pseudorandom bits. UUIDs are identifiers, not secret tokens. These definitions and cautions come from the current specification, RFC 9562.
This guide explains the differences, shows runnable Python and Node.js examples, and covers interoperability, canonicalization, security, storage, and troubleshooting. If you only need one default for ordinary record IDs, use a reputable library to generate UUIDv4 values from a sound random source.
1. UUID versions at a glance
| Version | How it is made | Good fit | Key caveat |
|---|---|---|---|
| v1 | Timestamp, clock sequence, and node field | Time-associated IDs where that construction is needed | Can expose creation ordering and node information |
| v3 | MD5 hash of namespace ID plus name, with UUID bits applied | Repeatable name-to-ID mapping with v3 compatibility | Namespace and name encoding must stay consistent |
| v4 | Random or pseudorandom bits, with required version and variant bits | Fresh IDs not derived from a name or timestamp | Quality depends on the random source; random ordering can reduce index locality |
| v5 | SHA-1 hash of namespace ID plus name, with UUID bits applied | Repeatable name-to-ID mapping using v5 | SHA-1 is part of the specified v5 construction; do not swap in another hash and call it v5 |
UUIDv1 has a 60-bit timestamp measured in 100-nanosecond intervals from 15 October 1582, plus a clock sequence and node field. The node may be an IEEE MAC address or a randomly derived value. UUIDv4 has 122 random bits after the required version and variant bits are set. UUIDv3 and v5 use a namespace UUID and the octets of a name to produce a deterministic result.

2. Choose the right version
Use v4 for independent identifiers
Use v4 when you need a new identifier for a record, request, or object and there is no stable natural name from which it should be derived. Use the language’s standard UUID library so randomness comes from the platform’s supported source. Distributed generation still relies on adequate random generation at each host. Collision probability is very small with a sound source, but uniqueness is an engineering assumption, not an integrity guarantee.
Use v5 or v3 for repeatable names
Use a name-based version when the same canonical name in the same namespace should produce the same UUID across runs or systems. Choose v5 for new work that needs the standardized SHA-1-based version. Choose v3 when compatibility with an existing v3 system is required. These are identifiers, not cryptographic proof that the name is authentic.
Define canonicalization as part of your application contract. Decide whether names are case-sensitive, how Unicode is normalized, and how URLs or paths are normalized. Two strings that look the same to a person can have different byte representations. If one service lowercases an email address and another does not, their generated UUIDs may differ.
Use v1 only when its time-based behavior fits
UUIDv1 contains timestamp and node information. That can be useful when the time-based construction itself is needed, but it can reveal approximate creation ordering and, depending on node generation, information about a network interface or its manufacturer. Consider these privacy implications before exposing v1 values publicly.
Consider v6 or v7 for time-ordered storage
If your actual goal is database insertion locality, compare UUIDv6 and UUIDv7, which RFC 9562 defines as time-ordered alternatives. Random v4 values can have poor database-index locality. The RFC does not promise a universal performance gain for a particular application; measure with your database and workload. Also avoid making a name-based UUID a primary key if the source name may change.
3. Generate UUIDs in Python
Python’s standard uuid module creates all four versions. Save this as uuid_examples.py and run it with Python 3:
import uuid
# v1: time-based. The node may expose host-related information.
u1 = uuid.uuid1()
# v3 and v5: deterministic for a namespace and identical name bytes.
name = "https://example.com/users/42"
u3 = uuid.uuid3(uuid.NAMESPACE_URL, name)
u5 = uuid.uuid5(uuid.NAMESPACE_URL, name)
# v4: random identifier.
u4 = uuid.uuid4()
for label, value in (("v1", u1), ("v3", u3), ("v4", u4), ("v5", u5)):
print(label, value)
# Repeating the same v5 call gives the same UUID.
assert uuid.uuid5(uuid.NAMESPACE_URL, name) == u5
Python provides standard namespaces including NAMESPACE_DNS, NAMESPACE_URL, NAMESPACE_OID, and NAMESPACE_X500. Use the namespace that matches the kind of name you are mapping. For an application-specific namespace, define and persist one UUID, then pass it as the namespace argument:
import uuid
APP_NAMESPACE = uuid.UUID("12345678-1234-5678-1234-567812345678")
canonical_name = "customer:42" # Define these rules and keep them stable.
value = uuid.uuid5(APP_NAMESPACE, canonical_name)
print(value)
The sample namespace above is only an example constant; generate and document a namespace for your own application instead of copying it as a shared production namespace.
4. Generate UUIDs in Node.js
Node.js installations commonly use the uuid package. Install it with npm install uuid, then save this as uuid-examples.mjs and run node uuid-examples.mjs:
import { v1, v3, v4, v5 } from 'uuid';
const urlNamespace = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
const name = 'https://example.com/users/42';
const values = {
v1: v1(),
v3: v3(name, urlNamespace),
v4: v4(),
v5: v5(name, urlNamespace),
};
console.log(values);
console.log(v5(name, urlNamespace) === values.v5); // true
Use a standard namespace that matches your name type, or create a stable application namespace and share it with every producer that must agree on IDs. Keep the argument order in mind: this package’s name-based functions take the name first and namespace second.
5. Make name-based UUIDs reproducible
- Choose a namespace. Pick the standard namespace for the name type, or define one stable application namespace UUID.
- Define the canonical name. Specify casing, Unicode normalization, separators, URL normalization, and any other transformations before deployment.
- Encode the same content everywhere. Name-based algorithms operate on octets. Different encodings or normalization rules can produce different results even when text appears identical.
- Choose v3 or v5 deliberately. Use v3 only when compatibility calls for it; otherwise use the standardized v5 construction. Don’t substitute a different hash and retain the v5 label.
- Protect the contract. Treat the namespace and canonicalization rule as versioned application behavior. Changing either changes generated IDs.
A useful test for your implementation is to generate a known name in two independent components and compare the resulting UUIDs. Include tricky inputs in your own test vectors: uppercase and lowercase, composed and decomposed Unicode, trailing slashes, percent encoding, and whitespace. Decide expected behavior first; there is no universal normalization policy for every application name.

6. Validate, store, and expose UUIDs safely
Most UUID libraries return a canonical textual representation with hexadecimal digits and hyphens. Store values in a native UUID column where your database supports one, or use a fixed-length representation with validation. Keep comparisons and API formats consistent across services. For name-based IDs, persist the namespace and canonicalization rules in documentation so another implementation can reproduce them.
Do not treat any UUID version as a bearer secret, password reset credential, authorization capability, or proof of integrity. RFC 9562 says: “Implementations SHOULD NOT assume that UUIDs are hard to guess.” Use a dedicated security mechanism for secrets and access control. The bits do not provide an integrity check that a person can reliably inspect.
7. Troubleshooting common problems
| Symptom | Likely cause | Fix |
|---|---|---|
| Two services produce different v3/v5 values | Different namespace, name bytes, case handling, Unicode normalization, or URL rules | Compare exact namespace UUID and canonical byte input. Define and test normalization at the boundary. |
| Repeated v4 calls return the same value in a test | A mock or seeded pseudo-random source is being reused, or the test is asserting the wrong behavior | Check test setup and runtime randomness. In production, use the library’s supported generator rather than implementing bit layout yourself. |
| v1 values expose unexpected metadata | The generator used a MAC-derived node or values are publicly observable | Avoid v1 if this disclosure is unacceptable; use v4 or a suitable time-ordered alternative for the actual requirement. |
| A custom hash output is called v5 | The implementation substituted a hash for the standardized SHA-1 construction | Use the specified v5 algorithm or, if a newer hash-based UUID is required, follow RFC 9562’s UUIDv8 guidance rather than mislabeling it v5. |
| IDs are unique but inserts are slow | Random insertion order may be affecting index locality | Profile database writes and indexes with representative load. Evaluate v6 or v7 if time ordering suits the data model. |
| UUID is accepted as an access token | Identifier and authorization credential were conflated | Replace it with an appropriately generated secret and enforce authorization separately. |
8. Performance, reliability, and cost
UUID generation is local computation and does not require a paid UUID service. For most applications, choose a standard library and focus engineering effort on correct version selection, stable name canonicalization, and the storage behavior of the consuming database. The relevant reliability concern differs by version: v4 depends on random-source quality; v3/v5 depend on identical namespace and input bytes; v1 includes clock and node behavior.
UUID text is 36 characters including hyphens; binary storage can be more compact where the database and application support it. The choice of textual versus binary storage is a system design decision. Check indexing, serialization, observability, and compatibility before changing representation. UUIDv6/v7 may be worth evaluating for locality, but benchmark in your own workload instead of assuming a universal improvement.
9. Or skip the browser setup
For a UUID generator, you generally do not need a browser or screenshot API. If your developer workflow also needs to capture rendered pages for documentation, QA, or an AI agent, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF; see the API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie and consent banners and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000, and every feature is on every plan. Sign up for 1,000 free screenshots a month, no card required.
10. FAQ
Which UUID version should I use by default?
Use v4 for a fresh independent identifier. Use v5 when stable name-derived output is part of the design.
Are v3 and v5 interchangeable?
No. They use different specified hash algorithms, so the same namespace and name produce different identifiers.
Can I use a UUID as a password reset token?
No. UUIDs are identifiers and should not be assumed difficult to guess. Use a purpose-built secret token.
Should I use v4 for database primary keys?
It can work, but random insertion order may affect index locality. Consider workload-specific measurement and compare v6/v7 when ordered insertion matters.
Will a name-based UUID change if I rename the record?
Yes, if the canonical name changes. Use an immutable name or store the generated UUID rather than expecting a mutable label to preserve identity.


