KSUID
Generate a KSUID string or write the bytes into a buffer. KSUID (K-Sortable Unique Identifier) is a 160-bit identifier consisting of a 4-byte timestamp (seconds since KSUID epoch: May 13, 2014) and 16 bytes of cryptographically random payload. Encoded as a 27-character Base62 string.Import
Function Signature
Basic Usage
Options
Configuration options for KSUID generation
Buffer Mode
Write KSUID bytes directly to a buffer at a specific offset:Configuration options (can be undefined)
Target buffer to write the KSUID bytes into (20 bytes required)
Byte offset in the buffer where KSUID should be written
Returns the same buffer instance that was passed in
Static Methods
toBytes()
Convert a KSUID string to a byte array.KSUID string in Base62 format (e.g., “2QnJjKLvpSfpZqGiPPxVwWLMy2p”)
20-byte array representation of the KSUID
fromBytes()
Convert a byte array to a KSUID string.20-byte array representing a KSUID
KSUID string in Base62 format (27 characters)
timestamp()
Extract the embedded timestamp from a KSUID string.KSUID string to extract timestamp from
Unix timestamp in milliseconds (for API consistency with ulid/uuidv7)
- KSUID only has second precision, so the returned millisecond timestamp will always end in
000 - The timestamp is returned in milliseconds (not seconds) for API consistency with
ulid.timestamp()anduuidv7.timestamp()
isValid()
Validate whether a value is a valid KSUID string (type guard).Value to validate
Type predicate:
true if the value is a valid KSUID string, false otherwise- Must be a string
- Must be exactly 27 characters
- Must match the pattern:
/^[0-9A-Za-z]{27}$/ - Must contain only Base62 characters
Constants
NIL
The nil KSUID (all zeros).MAX
The max KSUID (maximum valid value).KSUID Epoch
KSUID uses a custom epoch: May 13, 2014 00:00:00 UTC (Unix timestamp: 1400000000) This was chosen to:- Extend the lifetime of the timestamp field
- Start from a more recent date than Unix epoch (1970)
- Accommodate timestamps until approximately year 2150
Structure
KSUID format (160 bits / 20 bytes):Advanced Usage
Deterministic Generation (Testing)
Provide explicit options for reproducible KSUIDs:Custom Timestamp
Generate KSUIDs with a specific timestamp:Custom Random Source
Provide your own random bytes:Cloudflare Workers Note
By default, Cloudflare Workers “freeze” time during request handling to prevent side-channel attacks. This meansDate.now() returns the same value for the entire request duration.
Implications:
- All KSUIDs generated within a single request will have the same timestamp
- Sorting relies on the random payload bytes, not the timestamp
Errors
Thrown when options are invalid:
- Code:
KSUID_RANDOM_BYTES_TOO_SHORT- Random bytes length must be >= 16 - Code:
KSUID_TIMESTAMP_TOO_LOW- Timestamp must be >= KSUID epoch (1400000000)
Thrown when buffer offset is out of boundsCode:
KSUID_BUFFER_OUT_OF_BOUNDSThrown when parsing an invalid KSUID string format
Type Definitions
Comparison with Other IDs
| Feature | KSUID | UUID v7 | ULID |
|---|---|---|---|
| Format | 27-char Base62 | 36-char hex + hyphens | 26-char Base32 |
| Timestamp precision | Second (32 bits) | Millisecond (48 bits) | Millisecond (48 bits) |
| Randomness | 128 bits | 74 bits | 80 bits |
| Binary size | 20 bytes | 16 bytes | 16 bytes |
| URL-safe | Yes | No (hyphens) | Yes |
| Case-sensitive | Yes | No | No |
| Epoch | May 13, 2014 | Unix epoch | Unix epoch |
| Lexicographic sorting | Yes | Yes | Yes |
- KSUID has second precision (vs millisecond for UUID v7/ULID)
- KSUID has more randomness (128 bits vs 74-80 bits)
- KSUID is larger (20 bytes vs 16 bytes)
- KSUID uses Base62 encoding (case-sensitive)
Use Cases
KSUID is ideal for:- Distributed systems: High entropy prevents collisions
- Database keys: Sortable, no coordination needed
- Event ordering: Second precision is often sufficient
- Log aggregation: Sortable across services
- High-frequency events: Second precision may be too coarse (use UUID v7 or ULID instead)
- Case-insensitive systems: Base62 is case-sensitive
- Storage-constrained systems: 20 bytes is larger than UUID/ULID
Migration from @owpz/ksuid
If migrating from the@owpz/ksuid npm package:
- uniku uses a functional API (
ksuid()) vs class-based API (KSUID.random()) - uniku uses standard
Uint8Arrayinstead of Node.jsBuffer - uniku’s
timestamp()returns milliseconds (for API consistency) - uniku doesn’t include
Sequence,CompressedSet, or sorting utilities
