UUID, Nanoid, ULID: Choosing the Right ID Format
The Three Contenders
UUID v4
The most widely used identifier. 128 bits of randomness, formatted as
550e8400-e29b-41d4-a716-446655440000. Universally supported across
databases, languages, and frameworks.
Pros: ubiquitous, zero dependencies
Cons: not sortable, verbose (36 chars with hyphens)
Nanoid
A URL-safe 21-character ID using a 64-character alphabet by default.
V1StGXR8_Z5jdHi6B-myT
Pros: shorter, URL-safe, customisable alphabet and length
Cons: less universal support, no time ordering
ULID
A 26-character lexicographically sortable ID. The first 10 characters
encode a millisecond timestamp, the remaining 16 are random:
01ARZ3NDEKTSV4RRFFQ69G5FAV
Pros: sortable by creation time, monotonic within the same millisecond
Cons: leaks creation timestamp, fewer libraries
Generating via API
curl "https://api.toolkitapi.io/v1/devtools/generate-id?type=ulid&count=5" \
-H "X-API-Key: $API_KEY"
{
"ids": [
"01JQXYZ1234567890ABCDEFGH",
"01JQXYZ1234567890ABCDEFI",
...
]
}
Decision Matrix
| Need | Use |
|---|---|
| Maximum compatibility | UUID v4 |
| Database index performance | ULID (sortable → sequential writes) |
| Short URLs or tokens | Nanoid |
| User-visible codes | Nanoid with custom alphabet |
| Event logs, audit trails | ULID (time-ordered) |
Database Considerations
Random UUIDs fragment B-tree indexes over time, causing write amplification. ULIDs inserted in time order keep indexes largely sequential, improving insert throughput significantly on large tables.