← Back to Blog
🔑
Dev Tools

UUID Generator: What UUIDs Are and When to Use Them

A UUID, short for Universally Unique Identifier, is a 128-bit number typically represented as 32 hexadecimal digits grouped by hyphens into the format 8-4-4-4-12. An example looks like 550e8400-e29b-41d4-a716-446655440000. The defining property of a UUID is that it is unique across space and time, meaning no two properly generated UUIDs should ever be identical, regardless of when or where they were generated.

This uniqueness without coordination is what makes UUIDs useful. In a distributed system where multiple servers, services or devices are independently creating records, each component can generate its own identifiers without consulting a central authority and without risk of collision. The same property makes UUIDs useful in single systems where you want identifiers that are safe to generate at any layer without database round-trips.

UUID versions and when to use each

UUID version 1 generates identifiers based on the current timestamp and the MAC address of the network interface. Because it encodes the time and the generating device, version 1 UUIDs are sortable by creation time and reveal when and roughly where they were generated. This makes them useful for time-series applications but means they embed information about the generating system that may be undesirable from a privacy standpoint.

UUID version 4 generates identifiers using random numbers. The only structure is the version bits that identify it as a version 4 UUID. Everything else is random. Version 4 is the most commonly used UUID type for general purposes because it is simple to generate, reveals nothing about the generating system, and is statistically extremely unlikely to produce collisions even when generating millions of UUIDs.

The probability of generating two identical version 4 UUIDs is so small as to be practically impossible for any realistic workload. Generating one billion UUIDs per second for roughly 85 years would give you approximately a 50 percent chance of a single collision. For any normal application, the collision probability is zero for practical purposes.

UUID version 5 generates identifiers deterministically from a namespace and a name using SHA-1 hashing. Given the same inputs, version 5 always produces the same UUID. This is useful when you want a reproducible identifier for a specific entity that does not change over time and can be regenerated from its inputs without storing the UUID explicitly.

UUIDs as database primary keys

Using UUIDs as primary keys instead of sequential integers has genuine advantages and real trade-offs. The main advantage is that UUIDs can be generated by the application layer without a database round-trip to get the next sequential ID. This simplifies distributed architectures, makes it safe to create records in multiple places simultaneously, and avoids the coupling between application code and database that sequential IDs create.

The main trade-off is storage size and index performance. A UUID is 16 bytes compared to 4 bytes for a 32-bit integer or 8 bytes for a 64-bit integer. More importantly, random UUIDs do not sort in insertion order, which causes index fragmentation in B-tree indexes. Inserting new records requires writing to random positions in the index rather than appending to the end, which is slower and increases fragmentation over time.

Ordered UUIDs like UUIDv7, which encode a timestamp in the first bits to make them sortable, address the index fragmentation problem while preserving the decentralized generation advantage. For new applications choosing a primary key strategy, UUIDv7 offers a better trade-off than random UUIDv4 in most cases where sequential integers are not appropriate.

UUIDs in APIs and URLs

Many APIs use UUIDs as resource identifiers in URLs and responses. A user with the ID 550e8400-e29b-41d4-a716-446655440000 would be accessed at /users/550e8400-e29b-41d4-a716-446655440000. This approach makes it impossible to enumerate all users by incrementing an integer ID, which provides a degree of protection against scraping and unauthorized access to resource lists.

UUIDs in URLs are longer and less readable than integer IDs, which is a real usability trade-off. Sharing a URL with a UUID is less clean than sharing one with a short integer, and URLs with UUIDs are harder to type manually. For internal APIs and machine-to-machine communication, this matters little. For user-facing URLs that might be typed or shared, the readability trade-off may favor shorter identifiers.

Generating UUIDs for testing and development

During development, you frequently need UUID values to use as test data, to seed a database, to configure services that require UUID-format identifiers, or to test UUID parsing and handling in your application. Generating these manually is tedious and error-prone because the format requirements are strict.

A UUID generator produces correctly formatted identifiers on demand, allowing you to copy and use them immediately. Generating a batch of UUIDs for test data is faster and more reliable than constructing them character by character.

  1. Open the UUID Generator below.
  2. Select the UUID version you need, most commonly version 4.
  3. Choose how many UUIDs to generate.
  4. Copy the results for use in your application or test data.
💡 For new projects choosing a primary key strategy, consider UUIDv7 if your database supports it. The time-ordered prefix makes it sort-friendly in indexes while still supporting decentralized generation.

Generate UUIDs in any version instantly for development and testing.

Generating UUIDs in different languages

Most programming languages have built-in or standard library support for UUID generation. Python's uuid module provides uuid.uuid4() for random version 4 UUIDs. JavaScript in Node.js uses the crypto module's randomUUID method. Java has java.util.UUID.randomUUID(). PHP has the ramsey/uuid library as a common option. Go has the google/uuid package. Ruby's SecureRandom.uuid generates version 4 UUIDs. In each case the language handles the cryptographically secure random number generation internally.

Browser JavaScript can generate UUIDs using crypto.randomUUID() in modern browsers without any library dependency. For compatibility with older environments, the uuid npm package is the standard choice. The browser-native method is preferred where supported because it uses the platform's cryptographically secure random number generator directly.

Storing and indexing UUIDs efficiently

Many databases have a native UUID type that stores the 128-bit value in 16 bytes rather than the 36-character string representation. Using the native type rather than storing UUIDs as strings saves storage space and improves comparison and sorting performance because numeric comparison is faster than string comparison. PostgreSQL, MySQL and SQL Server all support native UUID storage.

The index performance problem with random UUIDs in B-tree indexes is significant enough that database architects working with high-insert workloads often reach for alternatives. Sequential UUIDs that maintain monotonic ordering, time-ordered UUIDs that embed a timestamp prefix, or simply using database sequences for internal primary keys while using UUIDs only for external-facing identifiers are all common approaches to managing this trade-off.

Caching systems that use UUIDs as cache keys behave differently from those using sequential integers because UUID lookups cannot take advantage of sequential access patterns. For most cache use cases this does not matter because cache lookups are individual point queries rather than range scans. For sequential scan operations over UUID-keyed data, the access pattern is effectively random, which should be accounted for in performance expectations.

UUID alternatives for specific use cases

For applications that require short identifiers suitable for display in URLs and user interfaces, UUIDs are often too long. Shorter identifier schemes like NanoID generate URL-safe identifiers in configurable lengths, allowing you to trade off collision probability against length based on your specific volume requirements. A 10-character NanoID has far more than enough uniqueness for most applications while being much easier to include in short URLs.

Sequential database identifiers remain appropriate for many use cases despite the advantages of UUIDs. Internal database foreign key relationships work efficiently with integer primary keys. Tables with very high insert volumes benefit from the sequential access pattern that integer auto-increment provides. A hybrid approach using integer primary keys internally and UUIDs as external-facing identifiers combines the performance advantage of integers with the enumeration resistance of UUIDs.

For microservices and distributed event systems, UUIDs serve as correlation identifiers that link related events across services. A request that enters a system at an API gateway receives a UUID that travels with every subsequent event, log entry and service call it triggers. When debugging a problem, filtering all system logs by this UUID shows the complete trace of everything that happened in response to the original request, across every service that processed it.

Feature flags and A/B testing systems use UUIDs to consistently assign users to experiment groups. Hashing the user's UUID with the experiment identifier produces a deterministic bucket assignment that does not change between sessions and does not require storing the assignment in a database. The user always gets the same variant without any state management overhead.