Skip to content

UUID Variants

James Brucker edited this page Jun 12, 2025 · 10 revisions

UUID are globally unique identifiers that are 16-bytes long. Downsides of UUID are:

  • database indices are fragmented
  • not chronologically ordered

Several variants exist: UUIDv1, UUIDv7, and ULID.

Below is a comparison highlighting their structure, properties, privacy considerations, and typical use-cases.

Feature UUIDv1 UUIDv7 ULID
Specification RFC 4122 IETF draft (UUIDv7, time-ordered) ULID spec
Bit Layout 60 bits timestamp + 48 bits node + 14 bits sequence 48 bits timestamp + 74 bits randomness + 6 bits version/variant 48 bits timestamp + 80 bits randomness
Timestamp Resolution 100 ns increments since 1582-10-15 1 ms since Unix epoch (1970-01-01) 1 ms since Unix epoch
Lexicographic Order Yes, if compared as raw bytes Yes, natural time ordering Yes, sorts by timestamp then random
Global Uniqueness Yes (node/MAC + sequence) Yes (timestamp + random) Yes (timestamp + random)
Privacy Leaks MAC or machine identifier No machine identifier; only time + random No machine identifier; only time + random
Spoof Resistance Weak (MAC can be spoofed; collisions if clock moves backward) Stronger (random cushion; monotonic if implemented carefully) Strong (monotonic cushion; collision risk only within same ms and same monotonic sequence)
Size on Disk/Index 16 bytes 16 bytes 16 bytes
Ease of Generation Widely supported in standard libraries Emerging support; requires up-to-date libraries Widely supported (multiple languages)
Use-Cases Legacy systems; when backward compatibility with UUIDv1 is required New applications needing RFC-style UUIDs with time order Time-sortable IDs with simple spec; especially JS/browser use

UUIDv1

  • Structure
    • 60 bits of a 100-nanosecond timestamp (since 1582-10-15)
    • 14 bit sequence (to avoid collisions within the same timestamp)
    • 48 bit “node” (MAC address or random fallback)
  • Pros
    • Naturally ordered by generation time
    • Supported everywhere (standard in most UUID libraries)
  • Cons
    • Reveals hardware/MAC address (privacy leak)
    • Vulnerable to clock regression (requires sequence bump)

UUIDv7 (Time-Ordered UUID)

  • Structure
    • 48 bit Unix-millisecond timestamp
    • 74 bit cryptographically random payload
    • 6 bit version/variant markers
  • Pros
    • Millisecond ordering of IDs (good for time-series indexing)
    • No hardware identifier
    • Fully compliant with the overall UUID format
  • Cons
    • Library support is still emerging (you may need a custom generator)
    • Less granular timestamp (millisecond vs. 100 ns)

ULID (Universally Unique Lexicographically Sortable Identifier)

  • Structure
    • 48 bit Unix-millisecond timestamp
    • 80 bit cryptographically random payload
  • Pros
    • Lexicographically sortable when encoded as Crockford’s Base32 (26 chars)
    • No hardware identifier, simpler spec than UUIDv7
    • Built-in monotonicity (“monotonic ULID”) to avoid collisions within the same ms
  • Cons
    • Not a UUID; may not integrate with libraries expecting RFC-4122 format
    • Slightly larger random payload than UUIDv7 (80 bits vs. 74 bits)

When to Choose Which?

  • UUIDv1: Legacy compatibility or when library support and fine-grained (100 ns) timestamps matter—and you can tolerate the MAC leak (or use a random node).

  • UUIDv7: If you want to stick with the UUID standard, need lexicographic time ordering, and don’t mind millisecond resolution (and you have a library that supports v7).

  • ULID: When you need simple, time-sortable IDs in environments like JavaScript/browser, prefer a compact Base32 string, and can adopt a non-UUID identifier.

Practical Tip

If you’re storing and indexing large, time-ordered logs (e.g. meter readings), time-ordered IDs (UUIDv7 or ULID) help keep your B-tree indexes hot at the “right” end—minimizing page splits and improving insert throughput. For most new projects, ULID is often the easiest to adopt; if you need strict UUID compatibility, go with UUIDv7.

Clone this wiki locally