Skip to content
100% in your browser. Nothing you paste is uploaded — all processing runs locally. Read more →

UUID vs CUID2

On this page
  1. What CUID2 is
  2. Side-by-side
  3. Where CUID2 wins
  4. Where UUID v7 wins
  5. Storage comparison
  6. When to choose CUID2
  7. When to choose UUID v7
  8. Code
    1. CUID2
    2. UUID v7
  9. CUID1 — don’t use
  10. Common pitfalls
  11. Decision flowchart
  12. Try the tools

TL;DR. CUID2 is a 24-character collision-resistant ID format designed for horizontal scaling. It’s shorter than UUID, uses a wider alphabet, and has strong statistical guarantees. For new code, UUID v7 is still the safer default because of universal ecosystem support, but CUID2 is a reasonable choice when you control all clients and want shorter strings.

What CUID2 is

CUID2 is the successor to CUID, designed by Eric Elliott. The format is 24 characters of lowercase alphanumerics:

clo7snjzj0000356ucudl3sn7

The string is generated from:

CUID2 specifically optimizes for:

  1. Horizontal scaling — no coordination needed, no host ID assignment.
  2. Collision resistance — even at billions of IDs across thousands of nodes.
  3. URL safety — no special characters, fixed width, lowercase only.
  4. Sortability — IDs are roughly time-ordered (more so than v4, less so than v7).

Side-by-side

UUID v7CUID2
Length (chars)36 (with hyphens)24
Encodinghex + hyphensbase36 lowercase alphanumerics
Bits of entropy~74 random~120 (different layout)
Time-orderedyes (lexicographic)yes (approximately)
StandardRFC 9562 (IETF)community spec
DB native typeyes (Postgres uuid, etc.)no (stored as text)
Prefix safe for URLsyesyes
Case-sensitiveno (canonical lowercase)yes (lowercase only)
Uses host fingerprintnoyes (privacy implication)

Where CUID2 wins

Where UUID v7 wins

Storage comparison

ApproachBytes per ID
Postgres uuid (UUID v7)16
Postgres text storing CUID2~25
Postgres char(24) storing CUID224
Postgres text storing UUID canonical~37

If you store CUID2 as char(24), the per-row size is 50% more than native UUID. At a billion rows, that’s ~10 GB difference in primary-key index alone.

When to choose CUID2

When to choose UUID v7

Code

CUID2

npm install @paralleldrive/cuid2
import { createId, isCuid } from "@paralleldrive/cuid2";

const id = createId();        // "clo7snjzj0000356ucudl3sn7"
const valid = isCuid(id);     // true

UUID v7

import { v7 } from "uuid";

const id = v7();              // "01928a47-3b30-7c5e-9d1a-f0b8c4a7e923"

Both are one-line generators. The library API surface is similar.

CUID1 — don’t use

CUID1 (the predecessor, format cjld2cyuq0000t3rmniod1foy) had known weaknesses around collision rate and timing-attack resistance. It’s deprecated. If a tutorial or older codebase says “CUID”, check whether it means CUID1 — and migrate to CUID2 (or UUID v7) if so.

Common pitfalls

Decision flowchart

Are you starting fresh and have no specific reason to choose either?
└── UUID v7

Do you control all clients and want shorter URLs?
└── CUID2 is reasonable, but consider UUID + base64url for similar length
    (22 chars) while keeping standard format

Do you cross system boundaries (multiple DBs, message queues, partners)?
└── UUID v7

Are you on a team that already uses CUID2 and likes it?
└── CUID2 (consistency beats marginal switching value)

Try the tools