If you have written a line of backend code in the last decade, you have probably typed uuid.v4() without thinking much about it. UUID v4 is the default choice in most frameworks for a reason: it is simple, unique, and requires no coordination between servers. But there are now better options for specific use cases — and understanding the differences will help you make the right call for your next project.
UUID stands for Universally Unique Identifier. It is a 128-bit value represented as 32 hexadecimal digits separated into five groups by hyphens:
550e8400-e29b-41d4-a716-446655440000
The format looks like this: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx, where M is the version digit and N is the variant. UUIDs are defined in RFC 4122 and are the de facto standard for unique identifiers in distributed systems.
The core promise of a UUID is that you can generate one on any machine, in any language, without contacting a central server — and it will almost certainly be unique. This makes them far more practical than auto-incrementing integers when you have multiple database nodes, generate IDs on the client before a round-trip to the server, or need to merge data from different sources without collisions.
UUID v4 is fully random. All 122 meaningful bits are generated using a cryptographically secure random number generator. The version digit is always 4 and the variant bits are always 10xx in binary.
It is the right choice for the vast majority of use cases: user IDs, session tokens, file upload identifiers, API keys, and anywhere else you need a unique identifier with no ordering requirement.
The one weakness of UUID v4 is exactly what makes it simple: it is random, so records added to a database are inserted at random positions in the B-tree index. As your table grows, this causes frequent page splits — the database engine has to break index pages apart to make room for new entries scattered throughout the key space. For large tables (tens of millions of rows), this degrades write performance noticeably.
UUID v7, standardised in RFC 9562 (2024), solves the index performance problem. The first 48 bits encode the current Unix timestamp in milliseconds, and the remaining bits are random. This means UUID v7 values are monotonically increasing — new records land at the end of the index, not in the middle, eliminating page splits.
UUID v7 is a direct improvement over the now-deprecated UUID v1 (which used a timestamp but leaked the server's MAC address). UUID v7 exposes only a timestamp, not any hardware identifier.
Use UUID v7 for:
The sortability also has a practical side benefit: you can often infer the approximate creation time of a record from its ID alone, without needing a separate created_at column.
ULID (Universally Unique Lexicographically Sortable Identifier) takes the same concept as UUID v7 — timestamp prefix plus random suffix — but uses a more readable encoding. Instead of hexadecimal with hyphens, ULID uses Crockford Base32: 26 characters from the alphabet 0123456789ABCDEFGHJKMNPQRSTVWXYZ (deliberately excluding easily confused characters like I, L, O, and U).
A ULID looks like this: 01ARZ3NDEKTSV4RRFFQ69G5FAV
ULIDs are case-insensitive, URL-safe, and sort lexicographically by creation time. Many developers find them more pleasant to work with in URLs, logs, and debug output because they are shorter and visually distinct from random noise.
The trade-off: ULIDs are not natively supported by most databases as a UUID type. You typically store them as TEXT or CHAR(26), which takes more storage than a 16-byte UUID binary type. For most applications this is irrelevant; for very high-volume tables it is worth considering.
Sequential integers (SERIAL, AUTO_INCREMENT) are the right choice when:
/posts/1042)UUIDs are the right choice when:
The "exposing record count" point is worth noting for business reasons. An auto-increment user ID tells anyone who signs up what their user number is — and therefore roughly how many users you have. Competitor research and media often note this. UUIDs give nothing away.
You can generate UUID v4, UUID v7, and ULIDs instantly using Criply's UUID generator. It uses crypto.randomUUID() and crypto.getRandomValues() — never Math.random() — so the output is cryptographically secure. Generate one at a time or bulk-generate up to 100, then copy all or download as a text file. No signup required.
For production code, use the official libraries for your language: the uuid package for JavaScript/TypeScript, uuid for Python, or the built-in gen_random_uuid() function in PostgreSQL (which generates v4 by default; v7 support was added in PostgreSQL 17).
7 practical ways to work with PDFs faster. Free, instant download.
Use our free UUID Generator tool — works in your browser, nothing to install.
UUID Generator — Free