UUID vs NanoID: Which Identifier Should You Choose?
Every system that stores or exchanges data eventually has to answer the same question: how should we identify a thing? Auto-incrementing integers are simple but leak information and break in distributed systems. The two most popular modern alternatives are UUIDs and NanoIDs, with ULIDs as an increasingly mainstream third option. The choice influences URL length, database performance, debuggability, and the resilience of your system against ID guessing.
This article compares them on the dimensions that actually affect production systems: collision probability, generation speed, sortability, URL safety, and how each behaves as a database primary key. There is no universally correct choice — only a correct choice for your use case.
The Contenders, At a Glance
| Format | Length | Bits of randomness | Sortable? |
|---|---|---|---|
| UUID v4 | 36 chars (32 hex + hyphens) | 122 | No |
| UUID v7 | 36 chars | 74 random + 48 ms timestamp | Yes (by time) |
| NanoID (default) | 21 chars | 126 | No |
| ULID | 26 chars (Crockford Base32) | 80 random + 48 ms timestamp | Yes (by time) |
Example outputs:
UUID v4: f47ac10b-58cc-4372-a567-0e02b2c3d479
UUID v7: 0191e3a1-7e08-7c00-a4e6-bf45ddc5c9b1
NanoID: V1StGXR8_Z5jdHi6B-myT
ULID: 01H8F2VWVT8QYZAB7Q9XKD4MNP
Collision Probability: Are They Actually Unique?
All four formats are practically collision-free for normal workloads, but the math matters when you scale into the billions. The relevant calculation is the birthday paradox: the probability of any collision after generating N IDs from a space of size 2^B.
For UUID v4 with 122 bits of randomness, you would need to generate about 2.7 × 10^18 IDs to have a 50% chance of a single collision. For NanoID's default 21-character alphabet (64 characters → 126 bits), the threshold is similar. To put that in perspective: at one million IDs per second, you would still need over 80,000 years to see one collision. For application-level identifiers, both are effectively unique.
The story changes if you trim NanoID. NanoID's appeal is its configurability — you can shorten it to, say, 10 characters for human-readable URLs. At 10 characters, the bit count drops to 60, and the safe-generation threshold becomes around 230,000 IDs before collision risk approaches one in a million. For per-tenant short URLs that is still fine; for global primary keys it is not.
Sortability and Database Performance
This is where the choice has the biggest engineering impact. UUID v4 and NanoID are fully random — adjacent inserts land in unrelated positions of any B-tree index, causing write amplification and inflated index sizes. On large tables, the difference between a random and a sortable primary key can be 2–3x in write throughput.
UUID v7 (standardized in RFC 9562 in 2024) and ULID solve this by encoding a 48-bit millisecond timestamp at the start of the ID. Adjacent IDs are nearly adjacent in lexicographic order, so new rows append cleanly to the right side of the index. If you store IDs in PostgreSQL, MySQL, or any B-tree backend, UUID v7 or ULID is the modern default — they keep the global-uniqueness benefit of UUIDs while behaving like sequential keys for indexing purposes.
URL Safety, Length, and Aesthetics
URL aesthetics matter for shareable links. Compare:
UUID v4 URL: /u/f47ac10b-58cc-4372-a567-0e02b2c3d479 (44 chars after /u/)
NanoID URL: /u/V1StGXR8_Z5jdHi6B-myT (24 chars)
Short NanoID (10 chars): /u/V1StGXR8_Z (12 chars)
NanoID is the clear winner for URL-shortener-style identifiers and any context where the ID is meant to be visible. The default alphabet uses URL-safe characters (A-Z a-z 0-9 _ -), so no URL encoding is required. UUIDs are usable in URLs but feel bureaucratic. For internal database keys, the visual difference matters less and you should let consistency and sortability decide.
If you need a single ID format that doubles as a public slug, NanoID has the edge. If you need rigorous standardization across vendors and tools (databases, libraries, log analyzers), UUID v7 wins. For one-off random tokens, you can also use a password generator set to a URL-safe alphabet — the same math applies, just without the named standard.
Security and Predictability
None of these formats should be used as a security token by themselves. They are identifiers, not secrets. A correctly generated UUID v4 or NanoID has enough entropy to be effectively unguessable, but UUID v7 and ULID expose the creation timestamp — useful for ordering, harmful when timing reveals information you wanted hidden. If your IDs appear in URLs where guessing would matter, audit your authorization checks first and choose the random variants (UUID v4 / NanoID) only as a defence-in-depth measure.
For true secrets — session tokens, password reset links, API keys — use a cryptographically secure random generator producing at least 128 bits, and treat the value as a credential (hash before storage, transmit over TLS only).
Frequently Asked Questions
Is UUID v4 deprecated?
No. UUID v4 remains valid and widely used. UUID v7 was added because v4's randomness is poor for database indexing, not because v4 itself is broken. New systems usually prefer v7; legacy systems can keep v4 indefinitely.
How do I decide between NanoID and UUID v7?
If the ID will appear in URLs or logs that humans read, NanoID is shorter and friendlier. If the ID is primarily an internal database key, UUID v7 fits better into existing tooling, supports time-based sorting natively, and is an official standard. Many systems use both — UUID v7 for primary keys, NanoID for public-facing slugs.
Can I use auto-increment integers in 2026?
Yes, if you have a single source of truth (one master database) and you do not mind exposing the creation order. They are smaller, simpler, and faster than any UUID. The reasons to switch are distributed generation (no central counter) and not leaking growth metrics through public IDs.