Overview
3 min readJun 27, 2024
Generating a unique ID in distributed systems is one of the most common problem to be solved. Here the use cases can be very different, but requirements mostly boils down to same. We all want something with least chances of conflicts, and still want to beautify as much as possible.
We’ll go over different approaches that are available today to compare the same, and go deeper to understand these.
UUID (v4)
- UUID (Universally Unique Identifier) v4 generates unique identifiers using random values.
- It consists of 128 bits, represented as 32 hexadecimal characters, split by hyphens (e.g., 550e8400-e29b-41d4-a716–446655440000).
- Widely used for database keys and distributed systems to ensure global uniqueness without coordination
PS: UUID v7 is not yet much used and validated in production, hence keeping it outside of the comparison for now.
Short UUID
- A Short UUID is a more compact representation of a standard UUID.
- It typically involves encoding the 128-bit UUID in a shorter format, such as Base58 or Base64, to reduce its length.
- Base58 encoding helps avoid ambiguous characters (0, O, I, l) to enhance readability by humans. Sample: 4SUc5nG7mrLQ8fTF5pZZ5D
- Base64 encoding represents binary data in a text string using 64 different ASCII characters. Sample: NDY0NjY1NTQ0MDAwMA==
- This can make it more human-readable and suitable for applications with length constraints. Useful for user-facing URLs, URL shortners, etc.
Nano ID
- Nanoid is a small, secure, URL-friendly unique string ID generator.
- Unlike UUIDs, nanoids are customizable in terms of which characters to choose, and size, can be significantly shorter while still maintaining a high level of entropy and uniqueness
- By default, NanoID uses a set of 64 URL-safe characters, which are a-z, A-Z, 0–9, and the symbols _ (underscore) and — (hyphen)
- It typically generates a string of 21 characters, providing a similar collision probability to UUID v4 but with a shorter, more compact format.
- Example: Jfd84kd9sHlMpaT7Y5xJ1
ULID
- ULID (Universally unique Lexicographically sortable IDentifier) generates 128-bit identifiers.
- It includes a time component (48 bits for milliseconds since Unix epoch — first 10 characters) and a random component (80 bits — remaining 16 characters), making these sortable by creation time.
- Example: 01ARZ3NDEKTSV4RRFFQ69G5FAV.
Comparison
Entropy
Entropy in Bits for Different Lengths
Length(in char) | UUID v4 | Short UUID | Nanoid | ULID
============================================================
12 | 48 bits | 48 bits | 72 bits | 60 bits
16 | 64 bits | 64 bits | 96 bits | 80 bits
18 | 72 bits | 72 bits |108 bits | 90 bits
32 |122 bits |122 bits |192 bits |128 bits
Collision Probability
Summary of collision probability (calculated using GPT)
Length(in char) | UUID v4 | Short UUID | Nanoid | ULID
=========================================================================
12 | ~2.7 days | ~2.7 days | ~5300 years | ~50 years
16 | ~200 years | ~200 years | ~1012 yeras | ~3 x 105 years
18 |~5300 years |~5300 years | ~1015 yeras | ~107 years
32 |~1017 years |~1017 years | ∞ | ∞
Performance
PFB the latencies taken using java libraries
Identifier | Library | Performance
========================================================================
UUID v4 | java.util.UUID | 0.5–1 µs
Short UUID | java.util.UUID + encoding | 2–5 µs
NanoID | com.aventrix.jnanoid.jnanoid.NanoIdUtils| 1–2 µs
ULID | de.huxhorn.sulky.ulid.ULID | 2–5 µs