Compact Base64-first Database-friendly UIDs
Compact
20 characters encode 120 bits of payload.
Efficient
Speedy encoding and decoding.
Compatible
Can be used in URLs, form-fields and as HTML attributes.
Lexicographically ordered
The bitstring and the encoded string sort the same.
Database-friendly
Time-prefix improves database locality and performance.
Structure of a BaseUid
A BaseUid consist of two parts:
- 48bits of POSIX time in nanoseconds, left-shifted by 2 bits1
- 72bits of randomness
These two parts are concatenated into a 120bit long bitstring:
The bitstring is encoded as an ASCII string using the lexicographically-ordered Base64 alphabet
-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz.
This produces an ASCII string of 20 characters, of which 8 characters represent the time-component and 12 characters represent the randomness-component.
Example
A BaseUid from the start of 2022 could be ANjssJkyfa3H00J9ZPJG.
ANjssJky is the timestamp-component for 2022-01-01T00:00:00Z and fa3H00J9ZPJG is the randomness-component that
differs with each generated value, even if the point in time stays the same.
Conversion to UUIDv8 Format
BaseUids can easily be converted into UUIDv8 format if required:
Implementations
Comparison with other UID formats
| Payload | Compact | Efficient | Compatible | Ordered | Database-friendly | |
|---|---|---|---|---|---|---|
| BaseUID | 120bits | ✔ Base64 | ✔ | ✔ | ✔ | ✔ |
| UUID text repr. | 128bits | ✖ Base16 | ✔ | ✖ | ✔ | ✖ |
| ULID | 128bits | 🞈 Base32 | 🞈 | ✖ | ✔ | ✔ |
| LexicalUUID | 128bits | ✖ Base16 | ✖ | ✖ | ✔ | ✔ |
| Flake | 128bits | ✔ Base62 | ✖ | ✖ | ❔ | ✔ |
| ShardingID | 64bits | ✖ Base10 | 🞈 | ✖ | ✔ | ✔ |
| KSUID | 160bits | ✔ Base62 | ✖ | ✖ | ✔ | ✔ |
| Elasticflake | 120bits | ✔ Base64 | ✔ | ✖ | ✖ | ✔ |
| FlakeID | 64bits | ✖ Base10/16 | ✔ | ✖ | ✔ | ✔ |
| Sonyflake | 63bits | ✖ Base10 | ✔ | ✖ | ✔ | ✔ |
| orderedUuid | 120bits | ✖ Base10 | ✔ | ✖ | ✖ | ✔ |
| COMBGUID | 120bits | ✖ Base10 | ✔ | ✖ | ✖ | ✔ |
| SID | 128bits | ✔ Base10/16/32/64 | ✔ | ✖ | ✔ | ✔ |
| pushID | 120bits | ✔ Base64 | ✔ | ✖ | ✔ | ✔ |
| XID | 96bits | 🞈 Base32 | ✔ | ✖ | ✔ | ✔ |
| ObjectID | 96bits | ✖ Base16 | ✔ | ✖ | ✔ | ✔ |
| CUID | 128bits | ✖ Base36 | ✖ | ✔ | ✖ | ✔ |
| TypeID | 128bits | 🞈 Base32 | ✖ | ✔ | ✔ | ✔ |
-
This selection ensures that the resulting Base64-encoded string starts with a letter for timestamps between the years 2021 and 2260. This allows the use of BaseUids without escaping or additional effort in places that do not allow values starting with a digit (such as HTML attributes values, which are required to be valid CSS identifiers). ↩