Quick Decision Matrix
Database Primary Keys
Recommended: UUID v7 or ULIDTime-ordered IDs improve database index performance and query efficiency.
URL Shorteners
Recommended: NanoidCompact, URL-safe characters keep URLs short and readable.
Prevent Enumeration
Recommended: CUID2Non-sequential IDs prevent attackers from guessing valid IDs.
Maximum Compatibility
Recommended: UUID v4Universal standard supported by virtually all databases and systems.
Distributed Systems
Recommended: ULIDSortable with high entropy, perfect for distributed generation.
Session Tokens
Recommended: Nanoid or CUID2Short, secure, and random for session management.
Detailed Comparison
Time-Ordered vs Random
Time-ordered IDs (UUID v7, ULID, KSUID) embed a timestamp and sort naturally by creation time:Benefits of time-ordering:
- Improved database index performance
- Natural chronological sorting
- Can extract creation timestamp
- Better locality in B-tree indexes
Characteristics Comparison
| Format | Time-Ordered | Length | Encoding | Entropy | Binary Size |
|---|---|---|---|---|---|
| UUID v4 | ❌ | 36 chars | Hex (with dashes) | 122 bits | 16 bytes |
| UUID v7 | ✅ | 36 chars | Hex (with dashes) | 74 bits* | 16 bytes |
| ULID | ✅ | 26 chars | Crockford Base32 | 80 bits* | 16 bytes |
| CUID2 | ❌ | 24 chars** | Base36 | High | No binary format |
| Nanoid | ❌ | 21 chars** | URL-safe Base64 | 126 bits | No binary format |
| KSUID | ✅ | 27 chars | Base62 | 128 bits* | 20 bytes |
* Time-ordered IDs allocate bits to timestamp, reducing random entropy. The entropy listed is for the random portion only.** CUID2 and Nanoid support custom lengths.
Use Case Recommendations
Database Primary Keys
Use UUID v7 or ULID for optimal performance:- You need RFC-standard compliance
- Your database has native UUID type support
- You want to extract timestamps:
uuidv7.timestamp(id)
- You want shorter string representation (26 vs 36 characters)
- You prefer case-insensitive encoding
- You’re using it in URLs or file names
URL Shorteners and Public IDs
Use Nanoid for compact, URL-friendly identifiers:- Compact (21 characters by default)
- URL-safe (no encoding needed)
- Customizable length and alphabet
- Fast generation
Preventing Enumeration Attacks
Use CUID2 when you need to prevent ID guessing:Distributed Systems
Use ULID or UUID v7 for collision-free distributed generation:- No coordination needed between nodes
- Timestamp prefix ensures global ordering
- High entropy prevents collisions
- Can merge and sort logs from multiple sources
Maximum Compatibility
Use UUID v4 when compatibility is paramount:- Legacy systems requiring RFC 4122 compliance
- Databases with native UUID type (Postgres, MySQL)
- When time-ordering isn’t needed
- Maximum interoperability
Performance Considerations
Generation speed varies significantly:| Generator | Performance |
|---|---|
| ULID | 85× faster than npm ulid |
| CUID2 | 8× faster than @paralleldrive/cuid2 |
| KSUID | 1.5× faster than @owpz/ksuid |
| UUID v7 | 1.1× faster than uuid@v7 |
| Nanoid | ~comparable to nanoid |
| UUID v4 | npm uuid is 1.1× faster |
Migration Paths
Switching from another ID library? Check the Migration Guide for:- Drop-in replacement instructions
- API differences to be aware of
- Breaking changes
- Compatibility notes
Decision Flowchart
Summary
Quick Reference Table
Quick Reference Table
| Scenario | Best Choice | Second Choice |
|---|---|---|
| Database primary keys | UUID v7 | ULID |
| URLs and short codes | Nanoid | CUID2 |
| Security tokens | CUID2 | Nanoid |
| Legacy compatibility | UUID v4 | UUID v7 |
| Distributed systems | ULID | UUID v7 |
| File names | ULID | Nanoid |
| Session IDs | Nanoid | CUID2 |
| Invoice numbers | CUID2 | UUID v4 |
Still unsure? Start with UUID v7 for database IDs and Nanoid for user-facing identifiers. Both are excellent general-purpose choices.
