Published: Updated:

UUID v4 vs. v7 vs. Nano ID: Which should you use?

Warning: Choosing the wrong identifier format can degrade database performance at scale.

What is a UUID?

A Universally Unique Identifier (UUID) is a 128-bit value designed to uniquely identify resources across distributed systems without requiring a central coordinating authority.

While the RFC 9562 standard defines eight versions, UUID v4 and UUID v7 are the two primary choices for modern application development.

UUID v4: Random identifiers

UUID v4 is the most widely adopted version. It consists of 122 pseudo-random bits, offering virtually zero chance of collision across distributed nodes.

UUID v4 Structure

UUID v7: Time-ordered identifiers

UUID v7 combines a 48-bit Unix timestamp (in milliseconds) with 74 bits of randomness. Because the most significant bits represent time, UUID v7 values sort chronologically. This time-ordered layout makes it ideal for database primary keys and clustered indexes.

UUID v7 Structure


How UUID generators create secure randomness

Functions like Math.random() generate pseudorandom numbers using predictable algorithms, making them unsuitable for secure IDs.

Modern runtimes and libraries – such as the Node.js crypto module or the uuid package – rely on Cryptographically Secure Pseudorandom Number Generators (CSPRNG). These generators call operating system APIs to seed from system entropy gathered from unpredictable hardware events.


Collision probability: Can two UUIDs collide?

MetricUUID v4UUID v7
Random bits12274
Collision windowEntire identifier spacePer millisecond
Practical riskNegligibleNegligible

To put 128-bit identifiers into perspective: if you generate one million IDs every second for the next 100 years, the probability of a single collision remains around 0.0001%.

UUID v7 trades 48 bits of randomness for a timestamp, but its 74 remaining random bits apply to a single 1-millisecond window. You would need to generate hundreds of billions of IDs within the same millisecond on a single machine to risk a duplicate – a scenario that physical hardware constraints make virtually impossible in real-world systems.


Database index performance: UUID v4 vs. UUID v7

For relational database primary keys, UUID v7 is the superior choice.

Relational databases like PostgreSQL store primary keys in a B-tree index. Because UUID v4 values are entirely random, each new insert lands at an unpredictable location in the index tree. As tables grow, this randomness forces the database engine to constantly swap pages in memory, leading to severe index fragmentation and elevated disk I/O.

Because UUID v7 values are sequential, new inserts append to the end of the B-tree leaf pages. This preserves memory cache locality and keeps write throughput predictable even as tables grow past millions of records.

If your dataset contains fewer than 10 million rows, this performance gap is often unnoticeable. In that case, UUID v4 remains attractive because modern JavaScript runtimes support it natively with crypto.randomUUID(), requiring no third-party dependencies.


When to use Nano ID

If you work in the JavaScript ecosystem, you have likely encountered Nano ID. Here is how it compares to standard UUIDs:

FeatureUUID (v4 and v7)Nano ID
Size36 characters (with hyphens)21 characters (default)
AlphabetHexadecimal (0-9, a-f)URL-safe (A-Z, a-z, 0-9, _, -)
StandardRFC 9562Library-specific

Nano ID is smaller and faster for public URLs. Because it uses a 64-character URL-friendly alphabet instead of 16 hexadecimal characters, it provides collision resistance comparable to UUID v4 in 21 characters instead of 36. This compact footprint makes it ideal for public URLs, shareable links, and short codes.

However, relational databases like PostgreSQL provide a native 128-bit UUID data type stored efficiently as 16 binary bytes. In contrast, storing a Nano ID requires a VARCHAR(21) or CHAR(21) column, which consumes more disk space and indexes less efficiently than a native binary UUID.

Rule of thumb: Use Nano ID for user-facing URLs and slug parameters. Use UUID for internal primary keys.


Summary: Which identifier should you choose?

  • UUID v7 – Choose for database primary keys and clustered indexes. Time ordering prevents B-tree fragmentation and maintains consistent insert throughput at scale.

  • UUID v4 – Choose for internal identifiers in zero-dependency environments. It is built into the native JavaScript crypto.randomUUID() API and requires no third-party packages.

  • Nano ID – Choose for public-facing URLs, invite tokens, and short codes where readable, compact strings improve the user experience.

Designing a database schema? Read my guide on how to store money in a database.