Try it now: UUID generator and UUID validator.
UUIDs in one paragraph
A UUID (Universally Unique Identifier) is a 128-bit value that identifies something without a central authority. It is written as 32 hex digits in the groups 8-4-4-4-12. Software on different machines can make UUIDs on its own and, if it follows the rules, the values will not clash. UUIDs are specified in RFC 9562 (May 2024), which replaced RFC 4122 from 2005 and added versions 6, 7 and 8. Microsoft calls them GUIDs. The ITU-T X.667 / ISO/IEC 9834-8 standard describes the same format.
The layout of the 128 bits
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
^ ^
| +-- N: variant (8, 9, a or b for the standard variant)
+------- M: version (1 to 8)
- 36 characters as text (32 digits and 4 hyphens), 16 bytes as binary.
- The version (4 bits) says how the rest was made. The variant (2 bits for the standard kind) says which layout rules apply.
- Special values: Nil
00000000-0000-0000-0000-000000000000and Maxffffffff-ffff-ffff-ffff-ffffffffffff.
The versions and when to use each
| Ver. | Source | Sortable | Reveals | Choose it when |
|---|---|---|---|---|
| 1 | Clock and node id | No | Time, often the machine | You must stay compatible with old systems (MySQL UUID() makes v1). |
| 3 | MD5 of name | No | Nothing | Compatibility only. |
| 4 | Random | No | Nothing | The default. Opaque ids. |
| 5 | SHA-1 of name | No | Nothing, but can be tested by guessing the name | The same input must give the same id. |
| 6 | v1 reordered | Yes | Time | You have v1 data and want order. |
| 7 | Unix ms + random | Yes | Time | New database keys. |
| 8 | Your own scheme | Your choice | Your choice | Special uses with a fixed internal layout. |
Version 2 (DCE security) exists but is almost never used. A good rule: v4 for opaque ids, v7 for keys. Details: UUID v4 and UUID v7.
How likely is a collision?
A v4 UUID has 122 random bits. The probability of at least one repeat among n values is about n2 / 2123. This reaches 50% at about 2.7 × 1018 UUIDs. A system that creates a billion per second would need around 85 years. For a table with a billion rows, the chance of any repeat is about 10-19. So collisions from luck are not a design concern. The real causes are: a weak random generator (Math.random(), a seed that is the same on every start), cloned virtual machines or containers that share state, and code that truncates the value (for example keeping only 8 characters, which gives just 32 bits).
UUIDs as database keys
- Type. PostgreSQL has
uuid(16 bytes). SQL Server hasuniqueidentifier. MySQL and MariaDB are best withBINARY(16)plusUUID_TO_BIN()/BIN_TO_UUID()in MySQL 8. Newer MariaDB has aUUIDtype. Storing the text inCHAR(36)uses more than twice the space, and every secondary index repeats it. - Index order. Random v4 keys insert at random places in a B-tree. On big tables this means page splits, a larger index and more cache misses. Time-ordered v7 keys insert at the end, like a sequence.
- Distributed ids. A UUID can be created in the application, before the insert, so the id is known early. It also avoids exposing a count of rows the way sequential integers do.
- Trade-offs. UUIDs are bigger than 8-byte integers, harder for people to read or type, and a v7 key leaks the creation time.
What a UUID does not do
- Not a secret. Even a v4 UUID should not be the only thing between a stranger and private data. Use access checks. For tokens, use a secure random token with enough bits, from a framework function made for the purpose.
- Not a hash of content. Except v3 and v5, a UUID says nothing about the data it names. For checksums, see the hash generator.
- Not private in v1 and v7. v1 can include the MAC address of a machine in old implementations and always has a time. v7 has a time. Both let someone work out when a record was created.
UUIDs against other kinds of id
| Id | Size | Sortable | Notes |
|---|---|---|---|
| Auto-increment integer | 4 or 8 bytes | Yes | Small and fast. Needs one database to hand out numbers. Easy to guess. |
| UUID v4 | 16 bytes | No | No coordination. Standard. Fragments large indexes. |
| UUID v7 | 16 bytes | Yes | No coordination, standard, index friendly. |
| ULID | 16 bytes (26 characters) | Yes | Similar to v7, shorter text, no native database type. |
| Snowflake-style | 8 bytes | Yes | Compact. Needs worker ids and a clock rule. |
| NanoID, short random strings | Choice | No | Short URLs. You decide the length and the collision risk. |
Create UUIDs in code
// JavaScript crypto.randomUUID(); # Python import uuid uuid.uuid4() uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org') # 886313e1-3b8a-5372-9b90-0c9aee199e5d // Java UUID.randomUUID(); UUID.nameUUIDFromBytes(bytes); // version 3 // C# Guid.NewGuid(); // Go uuid.New(); uuid.NewV7() # Ruby SecureRandom.uuid // PHP (ramsey/uuid or symfony/uid) Uuid::uuid4()->toString(); # Shell uuidgen
Best practices
- Pick the version for the job: v4 for opaque ids, v7 for keys, v5 for ids derived from a name.
- Always use a cryptographically secure random source.
- Store UUIDs in the native or a 16-byte binary type, not as long text.
- Use one text style across the system (lowercase with hyphens is the common choice) and compare them case-insensitively.
- Validate input from users with a strict pattern before it reaches a query.
- Do not cut a UUID to make it shorter. Use Base64URL (22 characters) or a different id type.
- Do not treat a UUID as a password or an access token.
All UUID tools on this site
- UUID generator (all versions and formats)
- UUID v4 generator and UUID v7 generator
- Bulk UUID generator
- GUID generator
- UUID validator