Skip to content
← Blog

UUID vs ULID: Which ID Format to Use?

7 min readArchitecture

Every application needs unique identifiers. The question is which format: UUID v4, UUID v7, ULID, or something else? Each has trade-offs in sortability, collision probability, database performance, and information leakage.

This guide compares the three most popular options so you can make an informed choice.

UUID v4: The Default Choice

UUID v4 (Universally Unique Identifier, version 4) generates 122 random bits in the standard 8-4-4-4-12 hex format:

550e8400-e29b-41d4-a716-446655440000

Advantages:

  • Universally supported — every language, database, and framework has UUID v4 support
  • No coordination needed — two systems can generate UUIDs independently with negligible collision probability (2^122 possibilities)
  • No information leakage — purely random, reveals nothing about creation time or order

Disadvantages:

  • Not sortable by time — random distribution causes B-tree index fragmentation in databases, leading to slower inserts and more page splits
  • Not human-readable — 36 characters of hex with dashes
  • No embedded timestamp — you cannot determine when a record was created from its ID

UUID v7: Sortable UUIDs

UUID v7 (defined in RFC 9562) embeds a millisecond-precision Unix timestamp in the first 48 bits, followed by random bits:

018f3e5c-5b00-7000-8000-1a2b3c4d5e6f
│                    │
└── timestamp ───────┘ random ──────┘

Advantages:

  • Time-sortable — UUIDs created later have higher values, matching insertion order
  • Database-friendly — sequential values reduce B-tree page splits and improve write performance
  • Standard format — uses the same 8-4-4-4-12 format as UUID v4, so existing UUID columns work without schema changes
  • Timestamp extractable — you can recover the creation time from the ID

Disadvantages:

  • Information leakage — the creation timestamp is readable by anyone who has the ID
  • Millisecond resolution — multiple IDs generated in the same millisecond are ordered by random bits, not guaranteed monotonic within that millisecond
  • Newer standard — some older libraries and databases do not yet have native UUID v7 support

ULID: Compact and Sortable

ULID (Universally Unique Lexicographically Sortable Identifier) uses a different format: a 48-bit millisecond timestamp followed by 80 random bits, encoded as 26 Crockford Base32 characters:

01ARZ3NDEKTSV4RRFFQ69G5FAV
│          │
└ timestamp┘ randomness ────┘

Advantages:

  • Shorter — 26 characters vs 36 for UUID
  • Case-insensitive — Crockford Base32 uses only uppercase letters and digits, no confusable characters (no I/L/O/U)
  • Time-sortable — lexicographic sort matches chronological order
  • Monotonic option — within the same millisecond, the random component can be incremented to guarantee ordering

Disadvantages:

  • Not a standard format — ULIDs cannot be stored in UUID database columns without conversion
  • Less ecosystem support — not natively supported by most databases and ORMs
  • Timestamp leakage — same as UUID v7

Head-to-Head Comparison

FeatureUUID v4UUID v7ULID
Length36 chars36 chars26 chars
FormatHex + dashesHex + dashesCrockford Base32
Sortable by timeNoYesYes
Timestamp embeddedNoYes (ms)Yes (ms)
Random bits1226280
Database column typeUUIDUUIDText or UUID (with conversion)
StandardRFC 9562RFC 9562Informal spec
Privacy (no time leak)YesNoNo

Database Performance Impact

In databases with B-tree indexes (PostgreSQL, MySQL, SQLite), random UUIDs (v4) cause index fragmentation because new values are inserted at random positions in the tree. This leads to:

  • More page splits during inserts
  • Lower cache hit ratio (pages are not sequential)
  • 2-5x slower bulk inserts compared to sequential IDs

UUID v7 and ULID solve this because their time-based prefix makes new values approximately sequential, appending to the end of the index rather than inserting in the middle.

Benchmarks (PostgreSQL, 10M rows):

  • Auto-increment integer: baseline
  • UUID v7: ~1.2x slower inserts, ~1.1x slower reads
  • UUID v4: ~2.5x slower inserts, ~1.3x slower reads

When to Use Each

UUID v4 — when you need maximum privacy (no timestamp leakage), universal compatibility, or are working with systems that only support UUID format. Good for user-facing IDs where you do not want to reveal creation order.

UUID v7 — when you need time-sorted IDs in a system that already uses UUID columns. The best choice for new projects using PostgreSQL, MySQL, or any database with native UUID support. Drop-in replacement for UUID v4 with better performance.

ULID — when you need shorter IDs, case-insensitive identifiers, or are building a system without UUID column constraints. Good for URLs, API keys, and systems where 26 characters is significantly better than 36.

Generate IDs

StackCache UUID & ULID Generator creates UUID v4, UUID v7, and ULID identifiers with cryptographic randomness, directly in your browser. Generate single IDs or batches of up to 100 — all locally with no server.

Try it yourself

Open the tool mentioned in this guide — it runs locally in your browser, no account needed.

Open tool