Universally Unique Lexicographically Sortable Identifier
UUID can be suboptimal for many uses-cases because:
- It isn't the most character efficient way of encoding 128 bits of randomness
- UUID v1/v2 is impractical in many environments, as it requires access to a unique, stable MAC address
- UUID v3/v5 requires a unique seed and produces randomly distributed IDs, which can cause fragmentation in many data structures
- UUID v4 provides no other information than randomness which can cause fragmentation in many data structures
Instead, herein is proposed ULID:
- 128-bit compatibility with UUID
- 1.21e+24 unique ULIDs per millisecond
- Lexicographically sortable!
- Canonically encoded as a 26 character string, as opposed to the 36 character UUID
- Uses Crockford's base32 for better efficiency and readability (5 bits per character)
- Case insensitive
- No special characters (URL safe)
- Monotonic sort order (correctly detects and handles the same millisecond)
Installation
npm install --save ulid
Import
TypeScript, ES6+, Babel, Webpack, Rollup, etc.. environments
// 01ARZ3NDEKTSV4RRFFQ69G5FAV
CommonJS environments
const ULID = ULID
AMD (RequireJS) environments
;
Browser
Usage
To generate a ULID, simply run the function!
// 01ARZ3NDEKTSV4RRFFQ69G5FAV
Seed Time
You can also input a seed time which will consistently give you the same string for the time component. This is useful for migrating to ulid.
// 01ARYZ6S41TSV4RRFFQ69G5FAV
Monotonic ULIDs
To generate monotonically increasing ULIDs, create a monotonic counter.
Note that the same seed time is being passed in for this example to demonstrate its behaviour when generating multiple ULIDs within the same millisecond
const ulid = // Strict ordering for the same timestamp, by incrementing the least-significant random bit by 1 // 000XAL6S41ACTAV9WEVGEMMVR8 // 000XAL6S41ACTAV9WEVGEMMVR9 // 000XAL6S41ACTAV9WEVGEMMVRA // 000XAL6S41ACTAV9WEVGEMMVRB // 000XAL6S41ACTAV9WEVGEMMVRC // Even if a lower timestamp is passed (or generated), it will preserve sort order // 000XAL6S41ACTAV9WEVGEMMVRD
Pseudo-Random Number Generators
ulid
automatically detects a suitable (cryptographically-secure) PRNG. In the browser it will use crypto.getRandomValues
and on node it will use crypto.randomBytes
.
Math.random
Allowing the insecure By default, ulid
will not use Math.random
, because that is insecure. To allow the use of Math.random
, you'll have to use factory
and detectPrng
.
const prng = // pass `true` to allow insecureconst ulid = // 01BXAVRG61YJ5YSBRM51702F6M
Use your own PRNG
To use your own pseudo-random number generator, import the factory, and pass it your generator function.
const ulid = // 01BXAVRG61YJ5YSBRM51702F6M
You can also pass in a prng
to the monotonicFactory
function.
const ulid = // 01BXAVRG61YJ5YSBRM51702F6M
Implementations in other languages
Refer to ulid/spec
Specification
Refer to ulid/spec
Test Suite
npm test
Performance
npm run perf
ulid
336,331,131 op/s » encodeTime
102,041,736 op/s » encodeRandom
17,408 op/s » generate
Suites: 1
Benches: 3
Elapsed: 7,285.75 ms