What Is a UUID?
A UUID (Universally Unique Identifier) is a 128-bit label used to identify information in computer systems. When formatted as a string, it looks like this:
550e8400-e29b-41d4-a716-446655440000
UUIDs follow the format defined in RFC 9562 (formerly RFC 4122). The 128 bits are divided into six fields separated by hyphens — the first three in big-endian, the last two in little-endian — which is why reading them byte-by-byte is trickier than it looks.
The key property of a UUID is uniqueness with negligible collision probability. With 2122 possible values (the other 6 bits are reserved for version and variant), the practical chance of generating a duplicate is zero for any dataset that fits in this universe.
UUID Versions Explained
There are several UUID versions, each using a different method to generate the 128-bit value. The version number is encoded in bits 49–52 (the first half of the third hyphen group).
UUID v1 — Time + MAC Address
UUID v1 combines a 60-bit timestamp (100-nanosecond intervals since the Gregorian calendar epoch) with a 14-bit clock sequence and the node's 48-bit MAC address. The MAC address is the biggest problem — it uniquely identifies the hardware that generated the UUID, leaking hardware metadata into distributed systems.
v1 is time-sortable (timestamps in the most-significant bits) but not recommended for modern use.
UUID v4 — Cryptographically Random
UUID v4 uses all 122 available random bits, with 6 bits fixed to indicate version 4 and variant. It is the most commonly used UUID version and the default choice for most applications. Collisions are mathematically improbable:
To have a 50% chance of generating one duplicate v4 UUID, you'd need to generate approximately 2.6 quintillion UUIDs. For context, humanity has generated fewer than 100 billion UUIDs in total history.
v4 UUIDs are not sortable — they reveal nothing about when or where they were created. They are ideal for session tokens, correlation IDs, and general-purpose unique identifiers where predictability doesn't matter.
UUID v7 — Time-Sortable (Modern Standard)
UUID v7 (introduced in RFC 9562) encodes a 48-bit Unix timestamp in milliseconds in the most-significant 48 bits, followed by version bits and random bits. This means:
- Lexicographic sort = chronological order. Sorting v7 UUIDs by their string representation produces the same order as sorting by creation time.
- No MAC address exposure. The remaining bits are random, not hardware identifiers.
- K-sortable. Database indexes that rely on B-tree ordering (most SQL databases) benefit from v7 because new rows don't cause index churn — they append rather than insert.
v7 is the recommended choice for database primary keys in systems where you want time-sortable IDs without the privacy issues of v1.
Comparison Table
| Version | Source Data | Sortable? | Privacy Risk | Best For |
|---|---|---|---|---|
| v1 | Timestamp + MAC | Yes | High (MAC exposed) | Legacy systems only |
| v4 | Cryptographic random | No | None | Session IDs, correlation IDs, general use |
| v7 | Timestamp + random | Yes | None | Database primary keys, event streams |
Generating UUIDs in Code
If you're building this into a project, here's how to generate v4 and v7 in JavaScript and Python.
JavaScript — v4 (Native)
// Modern browsers & Node.js 19+
const uuid = crypto.randomUUID();
console.log(uuid); // 550e8400-e29b-41d4-a716-446655440000
// Legacy fallback
const arr = new Uint8Array(16);
crypto.getRandomValues(arr);
arr[6] = (arr[6] & 0x0f) | 0x40; // version 4
arr[8] = (arr[8] & 0x3f) | 0x80; // variant
const hex = Array.from(arr, b => b.toString(16).padStart(2, '0')).join('');
const formatted = hex.slice(0,8) + '-' + hex.slice(8,12) + '-' +
hex.slice(12,16) + '-' + hex.slice(16,20) + '-' + hex.slice(20);
JavaScript — v7 (Custom Implementation)
function uuidv7() {
const ms = Date.now();
const rand = new Uint8Array(10);
crypto.getRandomValues(rand);
const ts = ms.toString(16).padStart(12, '0');
const ver = '7' + rand[0].toString(16).padStart(3, '0');
const rand_hex = Array.from(rand.slice(1), b => b.toString(16).padStart(2, '0')).join('');
const raw = ts + ver + rand_hex;
return [
raw.slice(0,8), raw.slice(8,12), raw.slice(12,16),
raw.slice(16,20), raw.slice(20,32)
].join('-');
}
Python
import uuid
# UUID v4
u4 = uuid.uuid4()
print(u4) # 550e8400-e29b-41d4-a716-446655440000
# UUID v7 (Python 3.11+)
u7 = uuid.uuid7()
print(u7) # 01920b3e-d29b-71d4-80ff-3e9a7c0d5e5f
UUID Format Options
The same 128-bit UUID can be represented in several string formats. The format you choose affects string length and database compatibility.
Standard (with hyphens)
550e8400-e29b-41d4-a716-446655440000
The canonical representation. 36 characters. Most database UUID types expect this format. Human-readable and commonly used in configuration files and APIs.
Compact (no hyphens)
550e8400e29b41d4a716446655440000
32 hex characters. Used in databases like MySQL where UNHEX() stores the raw bytes efficiently. Common in NoSQL systems and when optimizing storage size.
With Braces
{550e8400-e29b-41d4-a716-446655440000}
Wraps the standard format in curly braces. Common in Microsoft environments (.NET), some ORM conventions, and C# codebases. Avoid in URLs — the braces must be URL-encoded as %7B and %7D.
Case: Lowercase vs Uppercase
UUIDs are case-insensitive by spec — both a and A represent the same value. However:
- Most APIs use lowercase. Google Cloud, AWS, and most REST APIs expect lowercase UUIDs.
- .NET uses uppercase. Microsoft's Guid type typically serializes as uppercase.
- SnapUtils defaults to lowercase — it's the most widely compatible choice.
Bulk UUID Generation
Generating UUIDs one at a time is fine for development, but testing pipelines, database seeding, and load testing often need hundreds or thousands of UUIDs at once. SnapUtils supports generating up to 1,000 UUIDs in a single click.
Bulk generation is useful for:
- Database seeding. Populate test environments with realistic IDs before running integration tests.
- API testing. Batch-create resources in load testing suites like k6 or Locust.
- Fixture generation. Generate realistic data for QA environments without connecting to production.
- Migration scripts. Pre-generate IDs before inserting into a new schema.
UUID Validation
The UUID validator in SnapUtils checks two things: syntactic validity (does it match the UUID pattern?) and version detection (which UUID version is this?).
A valid UUID must:
- Be exactly 32 hex characters, or 36 with hyphens, or 38 with braces
- Have the correct version bits (4 for v4, 7 for v7, 1 for v1)
- Have the correct variant bits (RFC 4122 variant is 8, 9, A, or B in the 13th hex digit)
Note: Validation checks the format and version bits, but cannot verify that a UUID was actually assigned by the system it claims to be from. Anyone can construct a valid-looking v7 UUID by setting the correct timestamp bits. Always treat UUIDs as opaque identifiers, not as authenticated claims.
When to Use Each UUID Version
Use v4 when: You need unique identifiers for sessions, tokens, correlation IDs, event IDs, or general-purpose database columns where randomness is acceptable. v4 is the default because it has no entropy leakage and is trivial to generate.
Use v7 when: You need database primary keys that are time-sortable. v7 UUIDs inserted sequentially produce monotonic primary key values, which means B-tree index inserts are append-only rather than scattered throughout the tree — reducing index fragmentation and improving write performance.
Avoid v1 when: You are starting a new project. v1's MAC address exposure is a privacy concern in distributed systems, and its predictability (timestamps are guessable) makes it unsuitable for security-sensitive applications.
Using the Tool
The SnapUtils UUID Generator supports v1, v4, and v7 generation, bulk mode (up to 1,000 UUIDs), format options (lowercase/uppercase, with/without hyphens, with/without braces), validation with version detection, and one-click copy to clipboard. All generation is 100% client-side — nothing is sent to any server.
Generate UUIDs v1, v4, and v7 with one click — format, validate, and bulk generate in your browser.
Open UUID Generator →Frequently Asked Questions
Should I use UUID v4 or v7?
Use v4 for general-purpose unique identifiers where randomness is preferred and predictability doesn't matter. Use v7 for database primary keys where you need time-sortable UUIDs without exposing MAC addresses (unlike v1). v7 is the modern standard for this use case.
How is UUID v7 time-sortable?
UUID v7 encodes a Unix timestamp in the first 48 bits (millisecond precision), followed by random bits. Because the timestamp is in the most-significant bits, sorting v7 UUIDs lexicographically by their string representation produces chronological order. This makes them ideal as primary keys in databases.
Is UUID v1 safe to use?
UUID v1 is generally not recommended for new projects. It embeds the generating machine's MAC address in the last 48 bits, which can expose hardware and network information. It also has predictability concerns. For most use cases, v4 (random) or v7 (time-sortable) are better choices.
Can two UUIDs ever collide?
For UUID v4, the probability of collision is effectively zero for any realistic dataset. With 2^122 possible UUIDs, the birthday paradox means you'd need to generate 2.6 quintillion v4 UUIDs before a 50% chance of a single collision. UUID v7 also has negligible collision risk due to the random suffix bits.
How do I generate a UUID in JavaScript?
Modern browsers support crypto.randomUUID() natively. For older environments, use crypto.getRandomValues() to fill 16 bytes and set the version and variant bits manually: arr[6] = (arr[6] & 0x0f) | 0x40 for v4.
What is the best UUID format for MySQL vs PostgreSQL?
PostgreSQL has a native UUID type (stored as 16 bytes internally) — use the standard hyphenated format. MySQL 8.0+ also supports UUID() function but stores them as CHAR(36) by default. For compact storage in MySQL, use UNHEX() to store as BINARY(16).