Les pubs vous déplaisent ? Aller Sans pub Auj.

UUID vs ULID vs CUID Which Unique ID Should You Use?

Publié le
UUID vs ULID vs CUID: Which Unique ID Should You Use? 1
ANNONCE · Supprimer ?

Every database row, every API resource, every distributed event needs an ID. The problem isn’t generating one — it’s choosing the format that won’t bite you six months in when your Postgres indexes are fragmented and your URLs look like noise.

Here’s the full uuid generator comparison: UUID v4, UUID v7, ULID, CUID2, and Snowflake — what they are, where they break down, and which one you should actually use.

UUID v4: The Safe Default (With One Big Problem)

UUID v4 is 128 bits of randomness, formatted as 550e8400-e29b-41d4-a716-446655440000. It’s universally understood, supported in every language, every database, and every ORM on the planet.

The collision probability is effectively zero — you’d need to generate a billion UUIDs per second for 85 years before hitting a 50% chance of a single collision. That’s not a concern in practice.

The problem is ordering. UUID v4 is completely random, which means inserting rows into a UUID-indexed table scatters writes across the B-tree. At scale, this causes page splits, index fragmentation, and degraded insert performance. If you’re inserting thousands of rows per second into a MySQL or Postgres table with a UUID primary key, you will feel this.

UUID v4 is also 36 characters as a string — not URL-safe without encoding, and bloated compared to alternatives.

UUID v7: UUID v4’s Better Sibling

UUID v7 fixes the ordering problem. It’s a time-ordered UUID where the most significant bits encode a millisecond timestamp, and the rest is random. The result: 01875f3a-7b2d-7f8e-a3d1-4b2e6c1a0f93.

Rows inserted in time order stay roughly sequential in the index. That’s a significant win for write-heavy workloads. UUID v7 is compatible with all existing UUID infrastructure — same format, same field length, same library support expectations — while adding sortability.

The RFC was finalized in 2022 and library support is catching up fast. If you’re already using UUIDs and can’t change your schema, switching from v4 to v7 is low-risk and high-reward.

ULID: The Most Developer-Friendly Option

ULID (Universally Unique Lexicographically Sortable Identifier) encodes a 48-bit timestamp and 80 bits of randomness into 26 Base32 characters: 01ARZ3NDEKTSV4RRFFQ69G5FAV.

What makes it stand out:

  • Sortable by default — lexicographic sort is chronological sort
  • URL-safe — no hyphens, no special characters
  • Insensible à la casse — avoids the 0/O et 1/I ambiguity by excluding those characters from the alphabet
  • Compressible — 26 characters vs 36 for a UUID string

ULID is the most practical choice for new projects that don’t have legacy constraints. It’s sortable enough for most use cases, short enough for URLs, and readable enough that a human can copy-paste it without making transcription errors.

One caveat: if you generate multiple ULIDs within the same millisecond, the monotonic sort order is guaranteed per-process but not across distributed nodes. For most applications, that’s fine.

CUID2: Built for Distributed Systems

CUID2 is the successor to CUID, redesigned from scratch for security and collision resistance in distributed environments. A CUID2 looks like: clh3uj5ln0000qzrmn831mbhe.

It uses a SHA-3 hash of a combination of timestamp, counter, fingerprint (process ID + hostname), and random bytes. The fingerprint is the key difference — it’s designed specifically to prevent collisions when you’re running many ID generators simultaneously across many servers.

CUID2 is not sortable. It prioritizes collision resistance and unpredictability over time ordering. If you’re building a system where IDs are generated by untrusted clients or across a large number of independent nodes and security is a concern, CUID2 is worth the tradeoff.

For most backend APIs, it’s overkill.

Snowflake IDs: High Throughput, But You’re on Your Own

Snowflake IDs were invented at Twitter for generating unique IDs at millions per second across a distributed cluster. A Snowflake ID is a 64-bit integer: timestamp (41 bits) + datacenter ID (5 bits) + machine ID (5 bits) + sequence (12 bits).

They’re sortable, compact (fits in a BIGINT), and extremely fast. Discord, Instagram, and many high-scale systems use this pattern.

The catch: you need to manage machine IDs. That means a coordination service (ZooKeeper, etcd, a database table) to assign unique machine IDs to each ID generator. If two nodes share a machine ID, you get collisions. Setting that up correctly is non-trivial, and maintaining it is operational overhead.

Unless you’re generating hundreds of thousands of IDs per second, the complexity isn’t worth it.

The Comparison

UUID version 4 UUID v7 UDI CUID2 Snowflake
Sortable Non Oui Oui Non Oui
URL-safe No (hyphens) No (hyphens) Oui Oui Yes (integer)
Résistance aux collisions Very high Very high Haut Very high High (w/ coordination)
Complexité Aucun Aucun Aucun Faible Haut
Typical use case Legacy systems, general use DB primary keys APIs, URLs, new projects Distributed/untrusted clients High-throughput systems

Generating Each in Node.js

// UUID v4
import { v4 as uuidv4 } from 'uuid';
console.log(uuidv4()); // '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'

// UUID v7
import { v7 as uuidv7 } from 'uuid';
console.log(uuidv7()); // '01875f3a-7b2d-7000-8000-4b2e6c1a0f93'

// ULID
import { ulid } from 'ulid';
console.log(ulid()); // '01ARZ3NDEKTSV4RRFFQ69G5FAV'

// CUID2
import { createId } from '@paralleldrive/cuid2';
console.log(createId()); // 'clh3uj5ln0000qzrmn831mbhe'

// Snowflake (using @socialgouv/nextid for simplicity)
import Snowflake from '@socialgouv/nextid';
const snowflake = new Snowflake(1n); // machine ID = 1
console.log(snowflake.nextId().toString()); // '1641024000000000001'

You can test UUID generation directly with the IO Tools UUID Generator — it supports UUID v1 through v7 and bulk generation without installing anything.

Which One Should You Use?

Here’s the actual recommendation, not the cop-out “it depends” version:

  • New project, no legacy constraints: Utilisez UDI. Sortable, URL-safe, compact. It’s the best default.
  • Already using UUIDs, need better DB performance: Migrate to UUID v7. Drop-in upgrade, massive index win.
  • IDs generated by clients or across untrusted distributed nodes: Utilisez CUID2. The fingerprinting makes collision resistance robust even in adversarial conditions.
  • High-throughput platform (100k+ IDs/sec), willing to manage machine IDs: Utilisez Snowflake. Otherwise, don’t bother.
  • UUID v4: Only if you’re maintaining legacy code and can’t change the format. Stop using it for new tables.

The era of defaulting to UUID v4 for everything is over. ULID is the new default for most use cases, and UUID v7 is the right upgrade path if you’re already in UUID land. Pick one and move on.

Envie d'une expérience sans pub ? Passez à la version sans pub

Installez nos extensions

Ajoutez des outils IO à votre navigateur préféré pour un accès instantané et une recherche plus rapide

Sur Extension Chrome Sur Extension de bord Sur Extension Firefox Sur Extension de l'opéra

Le Tableau de Bord Est Arrivé !

Tableau de Bord est une façon amusante de suivre vos jeux, toutes les données sont stockées dans votre navigateur. D'autres fonctionnalités arrivent bientôt !

ANNONCE · Supprimer ?
ANNONCE · Supprimer ?
ANNONCE · Supprimer ?

Coin des nouvelles avec points forts techniques

Impliquez-vous

Aidez-nous à continuer à fournir des outils gratuits et précieux

Offre-moi un café
ANNONCE · Supprimer ?