UUID version 4 Generator Tool

Generate random UUIDv4s with customizable formatting.

Format:
Encoding:
?
?
?
    

Use these GUIDs at your own risk! No guarantee of their uniqueness or suitability is given or implied.

Your Daily Fortune


UUIDv4: The Developer's Guide to Random Identifiers

If you've spent any time in a modern codebase, you've seen the UUIDv4. It is the industry default for "I need a unique ID and I don't want to coordinate with a database." However, while it's incredibly convenient for the developer, it can be a nightmare for the Database Administrator. If you've noticed your insert rates dropping or your index sizes ballooning as your data grows, you've likely run into the "fragmentation" problem.

This guide breaks down the technical reality of UUIDv4, where it fits in your architecture, and when you should probably be using something else.

Why was UUIDv4 created?

The core problem UUIDv4 solves is "coordinated identity." In a classic monolithic app with a single database, you use an auto-incrementing integer. But in a distributed system—where you have microservices, offline mobile clients, or multiple database shards—you cannot have a single central counter. If every server had to ask a central authority for the "next ID," that authority would become a massive performance bottleneck and a single point of failure.

UUIDv4 was created to allow any process, anywhere, to generate a unique identifier independently with a mathematically negligible chance of a collision. It removes the need for synchronization, making it the backbone of distributed systems architecture.

Is it the same as a GUID?

For all practical purposes: Yes.

"GUID" (Globally Unique Identifier) is a term primarily used in the Microsoft ecosystem. "UUID" (Universally Unique Identifier) is the standardized term defined by the RFCs. While there were minor differences in early implementations, today, if a developer says GUID or UUID, they are almost certainly talking about the same 128-bit identifier.

Who uses it?

Pretty much every role in the software lifecycle touches UUIDv4:

  • Backend Engineers: Use them for primary keys in distributed databases and for generating correlation IDs to track a single request across ten different microservices.
  • Frontend Developers: Use them to generate unique keys for list rendering in React or Vue to avoid state bugs when elements are reordered.
  • Database Administrators (DBAs): Spend their time managing the fallout of UUIDv4, specifically dealing with B-Tree index fragmentation and storage bloat.
  • QA and Testers: Use them to generate unique mock data for integration tests so that test runs don't collide across different environments.
  • Security Engineers: Use them for session tokens or password reset identifiers because they are unguessable.

How is it used?

From a code perspective, it's a one-liner. You call a library, and it returns a 128-bit value, usually represented as a 36-character string (including hyphens).

In a typical production workflow:

  1. Generation: The application generates the ID using a cryptographically secure pseudo-random number generator (CSPRNG).
  2. Transmission: The ID is passed as a string in JSON payloads over REST or GraphQL APIs.
  3. Storage: The ID is stored in the database. Ideally, it's stored as a BINARY(16) or a native UUID type rather than a VARCHAR to save space.

Exactly how many bits are random, and why not all 128?

A UUIDv4 is 128 bits long, but it is not 100% random.

Exactly 122 bits are random.

Why not all 128? The UUID specification requires that the version and variant of the identifier be identifiable so that systems know how to parse the ID.

  • Version bits: 4 bits are used to specify the version. For UUIDv4, these bits are set to 0100 (binary for 4).
  • Variant bits: A few bits are used to specify the layout (the variant). For the most common variant, these bits are set to 10.

If all 128 bits were random, a system wouldn't know if it was looking at a v1 (time-based), a v4 (random), or a v5 (hashed) UUID. By sacrificing 6 bits for metadata, the system maintains compatibility across different programming languages and operating systems.

Is it suitable for databases?

This is the most contentious part of the UUIDv4 discussion. The short answer is: It depends on your index strategy.

If you use UUIDv4 as your Clustered Index (the default for Primary Keys in many engines), you are creating a performance debt. Because v4 is completely random, new rows are inserted into random locations in the B-Tree index. This causes "Page Fragmentation." The database has to constantly split pages and move data on disk to make room for the new random ID, which destroys write throughput and increases disk I/O.

Here is the breakdown by engine:

  • PostgreSQL: Very suitable. Postgres has a native UUID type. While random IDs still cause some fragmentation, Postgres's storage engine handles it better than most.
  • SQL Server: Dangerous if used as the Clustered Index. Use UNIQUEIDENTIFIER. If you must use UUIDs, consider making them non-clustered and using a BIGINT IDENTITY as the clustering key.
  • MySQL: Use BINARY(16). Do not store them as VARCHAR(36) or you will kill your performance. Like SQL Server, random inserts into a clustered index (InnoDB) will cause severe performance degradation over time.
  • Oracle: Use RAW(16). Oracle is efficient with raw bytes, but the random-insert problem persists.
  • SQLite: Use BLOB. It works, but be mindful of the fragmentation.
  • Amazon RDS / Azure SQL / Google Cloud SQL: Since these are managed versions of the above, the same rules apply. In these environments, where I/O is often the primary cost and bottleneck, the inefficiency of random UUIDs can actually increase your cloud bill.

When is it appropriate (or not) to use a UUIDv4?

Appropriate Use Cases:

  • Public-facing IDs: When you need an ID for a URL that is impossible for a malicious user to guess (prevents "ID enumeration" attacks).
  • Temporary Objects: When you need a unique key for an object that exists only in memory during a single request.
  • Distributed Generation: When you need to generate an ID on a mobile device while offline and sync it to a server later without risk of conflict.
  • Non-Indexed Fields: When the ID is just a field for lookup and not the primary clustering key of the table.

Inappropriate Use Cases:

  • High-Volume Primary Keys: If you are inserting millions of rows per day into a relational database, avoid v4 as the clustered index.
  • Time-Sensitive Data: If you need to know when a record was created or want to sort records by creation time, v4 is useless.
  • Small-Scale Storage: If you are extremely constrained on storage space, a 4-byte integer is far more efficient than a 16-byte UUID.

Is it sortable?

No.

By design, UUIDv4 is random. If you sort a list of UUIDv4s, the result is a random shuffle. There is no chronological order, no sequential logic, and no way to perform range scans based on when the ID was generated. If you need sortability, you have to add a created_at timestamp column and index that separately.

Is it suitable for URLs?

Yes, but with a caveat. UUIDv4 is excellent for URLs because it prevents "ID scraping." If your URL is myapp.com/order/123, it's easy for a bot to try 124, 125, etc. A UUIDv4 makes this impossible.

However, they are bulky. A 36-character string is long. If you are building a URL shortener or a system where brevity is key, a UUIDv4 is too long. For those cases, something like NanoID is a better fit.

Comparison with other UUID versions and identifiers

The "UUID" family has evolved to solve the problems that v4 created.

  • UUIDv1: Combines time and the MAC address. It's sortable-ish but leaks the hardware ID of the server, which is a security risk.
  • UUIDv3 & v5: Name-based (MD5 and SHA-1). These are deterministic; if you give them the same input, you get the same ID. Not useful for primary keys.
  • UUIDv6: A recent attempt to make UUIDs sortable by rearranging v1 bits.
  • UUIDv7: The modern successor. UUIDv7 is very similar to ULID (timestamp + randomness). If you need a standard that is both globally unique and database-friendly, v7 is the current gold standard.
  • ULID: Not an official UUID version, but a 128-bit compatible identifier that is lexicographically sortable and uses a more compact Base32 encoding.
  • NanoID: Not a 128-bit identifier. It's a compact, URL-friendly string. While great for frontend IDs, it lacks a timestamp and suffers from the same index fragmentation as UUIDv4.

Comparison Table

Identifier Bit Length Sortable Collision Risk Primary Storage Encoding
UUIDv1 128 Yes Low Binary/UUID Hex
UUIDv4 128 No Very Low Binary/UUID Hex
UUIDv6 128 Yes Low Binary/UUID Hex
UUIDv7 128 Yes Very Low Binary/UUID Hex
ULID 128 Yes Very Low Binary/UUID Base32
UULID 128 Yes Very Low Binary/UUID Hex
NanoID Variable No Low String Alphabet

Final Architecture Advice

If you are starting a new project today, stop using UUIDv4 as your primary key.

The "randomness" that makes UUIDv4 great for security makes it terrible for database performance. If you need a globally unique identifier that doesn't kill your B-Tree indexes, move to UUIDv7 or ULID. Use UUIDv4 only for things that actually need to be random and non-sequential, such as session tokens, password reset tokens, or public-facing API keys.


What is the UUIDv4 Text Layout?

xxxxxxxx
-
xxxx
-
4 Version
xxx
-
y Variant
xxx
-
xxxxxxxxxxxx
Total: 36 characters
x = Random hexadecimal digit
4 = UUID version (0100)
y = Variant nibble (8, 9, A, or B)

What is the UUIDv4 Binary Bit Layout?

32 Random Bits
16 Random Bits
Version
0100b
12 Random Bits
Variant
10b
14 Random Bits
48 Random Bits
Total: 128 bits
Random: 122 bits
Reserved: 6 bits (Version + Variant)
Version:0100b (UUID version 4)
Variant:10b (RFC 9562 / RFC 4122 variant)