| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .gitignore | ||
| .markdownlint.jsonc | ||
| LICENSE | ||
| README.md | ||
Howion's Unique IDentifier (HUID)
1. Introduction
This document specifies Howion's Unique IDentifier (HUID).
HUID is a 63-bit, time-sortable integer identifier composed of:
- a millisecond timestamp component, and
- a random entropy component.
This document is the concise normative specification for HUID.
2. Motivation and Design Goals
HUID is designed for systems that require:
- compact identifiers that fit naturally in signed 64-bit integer storage,
- fast generation and parsing, and
- numeric ordering correlated with generation time.
Compared to 128-bit identifier families, HUID intentionally optimizes for storage and index locality in common database systems (for example, PostgreSQL BIGINT + B-tree indexes). HUID does not embed machine identifiers, sequence counters, or version marker bits inside the identifier body.
On modern 64-bit CPU architectures and database engines, arithmetic, comparison, and index-key handling for 64-bit integers are a natural fast path. HUID is designed to stay on this path.
Non-goals include global strict monotonicity under concurrency and embedding deployment topology (node/worker identity) into the identifier.
3. Notation
3.1. Language
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 RFC2119 and RFC8174 when, and only when, they appear in all capitals.
3.2. Terms and Abbreviations
- CSPRNG: Cryptographically Secure Pseudorandom Number Generator
- Unix time (ms): milliseconds since 1970-01-01T00:00:00Z
- HUID epoch: 2026-01-01T00:00:00.000Z (Unix
1767225600000with ms precision) - Canonical value: the integer value in the closed interval
[0, 2^63 - 1]
4. HUID Format
4.1. Value Domain
A HUID value is an integer in the inclusive range: 0 to 2^63 - 1.
Implementations MUST reject values outside this range as invalid HUIDs.
This range is intentionally chosen so that HUID values can be stored in a signed 64-bit integer while remaining non-negative.
Any input that is not an integer in this interval MUST be treated as invalid.
4.2. Bit Layout
HUID is composed of 63 payload bits:
- 42-bit time component (most significant bits)
- 21-bit random component (least significant bits)
In bit index form (most significant to least significant):
bits[62..21]:time_ms_since_2026_epochbits[20..0]:random_21_bits
or, equivalently id = (time << 21) | random.
4.3. Time Window
The 42-bit time field represents milliseconds since the HUID epoch.
- Minimum representable time offset:
0 - Maximum representable time offset:
2^42 - 1
Therefore, the valid wall-clock generation interval is: 2026-01-01T00:00:00.000Z through 2165-05-15T07:35:11.103Z.
Implementations MUST fail generation when the current clock falls outside this interval.
5. Generation
To generate a HUID:
- Read current Unix time in milliseconds
unix_ms. - Compute
time = unix_ms - HUID_EPOCH_MSwhereHUID_EPOCH_MS = 1767225600000. - If
time < 0, generation MUST fail. - If
time > (2^42 - 1), generation MUST fail. - Generate
random, a uniformly distributed 21-bit integer using a CSPRNG. - Return
id = (time << 21) | random.
Generation does not require coordination state (worker ID, sequence counter, or lock service).
6. Ordering and Collision Properties
6.1. Ordering
- HUID values are numerically sortable by
(time, random). - For differing millisecond timestamps, numeric order matches timestamp order.
- Within the same millisecond, order is determined by random bits and is not monotonic by generation call order.
6.2. Collision Model
Within a single millisecond bucket, the random space is 2^21 values.
- Collision probability is non-zero for multiple IDs generated in the same millisecond.
- Implementers SHOULD model expected per-millisecond burst rates and assess collision tolerance with birthday-bound analysis.
- Workloads requiring strict per-millisecond uniqueness guarantees SHOULD use additional coordination or a different scheme.
6.3. Database Index Locality Notes (Informational)
In B-tree indexes, key shape influences write distribution.
- A strictly increasing tail sequence can concentrate concurrent inserts at right-most leaf pages.
- HUID keeps a time-ordered high part for range locality, while randomizing low bits within a millisecond bucket.
- This random tail can reduce same-page insert concentration under high concurrent same-millisecond writes, at the cost of less strict in-page locality than a pure counter tail.
Therefore, random tail bits are a deliberate trade-off for stateless generation and better concurrent write dispersion in common B-tree workloads.
7. Encoding and Interoperability
7.1. Numeric Representation
The canonical logical value is a non-negative integer in [0, 2^63 - 1].
HUID defines no UUID-like canonical textual format (no fixed hyphenated layout, no base32/base36 canonical alphabet) by design.
If a string form is required, base10 decimal string representation is RECOMMENDED for textual interchange.
Rationale:
- It maps directly to the canonical integer value.
- It avoids alphabet/case normalization rules.
- It is compact for 63-bit values (up to 19 digits), while preserving straightforward interoperability with SQL and JSON ecosystems.
When ordering in text form is required, implementations SHOULD sort by numeric value (or by fixed-width zero-padded decimal) rather than naive lexicographic decimal string order.
7.2. Binary Representation
When serialized to bytes, HUID SHOULD be encoded as:
- exactly 8 octets,
- unsigned big-endian integer,
- with the most significant bit of the first octet equal to
0.
Decoders MUST reject payloads that decode to values greater than 2^63 - 1.
8. Best Practices
- Use signed 64-bit integer columns (
BIGINT, equivalent) for storage. - Index directly on the numeric value for efficient range and time-window queries.
- Prefer integer storage and transport; use decimal string only when the protocol or language cannot safely carry 64-bit integers.
- Use a high-quality CSPRNG provided by the host runtime or operating system.
- Ensure system clocks are synchronized (for example via NTP) to preserve expected temporal ordering semantics.
- Treat HUID as an identifier, not as an authentication secret or capability token.
9. Comparison to Related Schemes
The following comparison is informational.
| Scheme | Total bits | Time-sortable | Random bits | Coordination bits |
|---|---|---|---|---|
| HUID | 63 | Yes (ms bucket) | 21 | None |
| UUIDv4 (RFC9562) | 128 | No | 122 (effective) | None |
| UUIDv7 (RFC9562) | 128 | Yes | 74 random/counter bits | None required by spec |
| Snowflake | 63 | Yes | Typically 0 random bits | Worker + sequence |
Notes:
- Compared to UUIDv4 and UUIDv7, HUID prioritizes compactness (63 bits) over entropy width.
- Compared to Snowflake, HUID avoids embedding node identity and sequence state, trading deterministic per-node uniqueness for simpler stateless generation.
- Compared to ULID/KSUID-class identifiers, HUID is optimized for numeric 64-bit storage and indexing.
10. Security Considerations
HUID is not designed to hide generation time.
- The upper 42 bits reveal millisecond time relative to a fixed epoch.
- The random component is only 21 bits; brute-force within a known millisecond bucket is feasible.
- HUID MUST NOT be used as a bearer secret, password reset token, or cryptographic nonce.
If unpredictability is security-critical, systems SHOULD use dedicated high-entropy tokens separate from HUID.
11. Implementation Status (Informational)
The official reference implementation (in TypeScript) is available at github.com/howionlabs/huid-ts. It is informative and does not override this specification.
12. References
- RFC2119 - Key words for use in RFCs
- RFC8174 - Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words
- RFC9562 - Universally Unique IDentifiers (UUIDs)
- PostgreSQL Numeric Types (
bigint) - PostgreSQL Indexes and
ORDER BY(B-tree) - Twitter Snowflake (archived source)
- ULID canonical specification
- KSUID reference repository
License
This specification is licensed under the CC-BY-SA 3.0 © 2026 Howion Inc.
Appendix A. HUID Example
Given:
unix_ms = 2026-01-01T00:00:00.123Ztime = 123random = 0x15555(decimal87381)
Then:
id = (123 << 21) | 0x15555id = 258037077
Decoding 258037077:
time = 258037077 >> 21 = 123random = 258037077 & 0x1fffff = 87381decoded_unix_ms = 1767225600000 + 123 = 1767225600123