Skip to content
Retour au blog
Tutoriels

UUID v4 vs v7 vs ULID vs Snowflake : Guide de sélection (2026)

Guide pratique de sélection d'identifiants distribués : UUID v4, v7, ULID, Snowflake ID et NanoID comparés sur les performances, la triabilité et le support écosystème.

Go Tools Team 15 min de lecture

UUID v4 vs v7 vs ULID vs Snowflake : Choisir le bon identifiant pour votre base de données en 2026

Choisir le mauvais schéma d’identifiants peut coûter cher. Des clés primaires UUID v4 aléatoires sur une table de 100 millions de lignes causent jusqu’à 10 fois plus de divisions de pages d’index que des identifiants séquentiels. Les Snowflake ID nécessitent un registre central de workers qui devient un point de défaillance unique. ULID semblait être le compromis parfait — jusqu’à l’arrivée de UUID v7 en tant que standard IETF.

Ce guide vous fournit un cadre de décision, des chiffres de performance concrets et des exemples de code pour choisir le bon identifiant pour votre système.

Arbre de décision rapide

Votre besoinMeilleur choixPourquoi
Clé primaire en base de données (nouveau projet)UUID v7Ordonné par le temps, type de colonne uuid standard, meilleures performances d’index
Identifiant unique généraliste (pas besoin d’ordre)UUID v4Support universel, zéro configuration, 122 bits d’aléatoire
Identifiant déterministe à partir d’entrées connuesUUID v5Le même namespace + nom produit toujours le même UUID
Système distribué à haut débit (>100K ID/sec/nœud)Snowflake IDEntier 64 bits, monotone par worker, stockage natif BIGINT
Token URL-safe court ou identifiant côté clientNanoID21 caractères, alphabet URL-safe, longueur personnalisable
Système existant utilisant déjà ULIDULIDGardez-le — fonctionnellement équivalent à UUID v7, la migration n’en vaut pas la peine

Analyse approfondie des versions UUID

UUID v1 — Horodatage + adresse MAC (Obsolète)

UUID v1 encode un horodatage de 60 bits et l’adresse MAC de 48 bits de la machine. C’était le premier « UUID triable », mais il présente deux défauts fatals : il expose l’identité matérielle et utilise une époque non standard (15 octobre 1582). RFC 9562 déprécie formellement v1 en faveur de v6/v7. N’utilisez pas v1 dans les nouveaux projets.

UUID v4 — Aléatoire pur

UUID v4 remplit 122 de ses 128 bits avec des données aléatoires cryptographiquement sécurisées. C’est la version la plus utilisée — simple, privée et universellement supportée.

Points forts :

  • Zéro configuration, aucune coordination nécessaire
  • Totalement anonyme — aucun horodatage ni information matérielle exposés
  • Supporté par toutes les bases de données, langages et frameworks

Point faible :

  • La distribution aléatoire cause la fragmentation des index B-tree. Sur des tables en écriture intensive de millions de lignes, les clés primaires v4 peuvent dégrader les performances d’insertion de 2 à 10 fois par rapport aux identifiants séquentiels en raison de divisions de pages excessives.
// Générer UUID v4 — intégré dans tous les navigateurs modernes et Node.js
const id = crypto.randomUUID();
// → "550e8400-e29b-41d4-a716-446655440000"

UUID v5 — Hachage déterministe

UUID v5 hache un UUID de namespace et une chaîne de nom en utilisant SHA-1 pour produire un UUID déterministe. Les mêmes entrées produisent toujours la même sortie.

Cas d’utilisation : générer des identifiants stables à partir d’URL, de noms DNS ou de toute entrée reproductible. Préférez v5 à v3 (qui utilise le MD5, plus faible).

import uuid

# Mêmes entrées → même UUID, à chaque fois
id = uuid.uuid5(uuid.NAMESPACE_DNS, "example.com")
# → "cfbff0d1-9375-5685-968c-48ce8b15ae17"

UUID v7 — Aléatoire ordonné par le temps (Recommandé)

UUID v7 (RFC 9562, mai 2024) encode un horodatage Unix de 48 bits en millisecondes dans les bits de poids fort, suivi de 74 bits d’aléatoire cryptographique.

Pourquoi v7 est le nouveau choix par défaut pour les clés de base de données :

  • Insertions séquentielles : les nouveaux UUID sont toujours supérieurs aux précédents (à la milliseconde près), donc les insertions B-tree s’ajoutent toujours à la fin de l’index
  • Jusqu’à 90 % de divisions de pages en moins par rapport à v4 sur les charges en écriture intensive
  • Tri chronologique naturel sans colonne created_at supplémentaire
  • Type de colonne uuid standard — aucun changement de schéma nécessaire pour migrer depuis v4
  • 74 bits d’aléatoire — suffisant pour pratiquement toutes les applications (v4 en a 122)

Compromis : l’horodatage de création est intégré dans l’identifiant. Si vous avez besoin d’identifiants opaques ne révélant pas l’heure de création, restez sur v4.

// Génération UUID v7 (Node.js 20+)
import { v7 as uuidv7 } from "uuid";
const id = uuidv7();
// → "01906b5e-4a3e-7234-8f56-b8c12d4e5678"
// Les anciens ID se trient toujours avant les nouveaux

Performances PostgreSQL et MySQL : v4 vs v7

Benchmarks sur une table PostgreSQL 16 de 50 millions de lignes (clé primaire B-tree) :

MétriqueUUID v4UUID v7Amélioration
Débit d’insertion (lignes/sec)12 40028 6002,3x plus rapide
Taille d’index après 50M lignes4,2 Go2,8 Go33 % plus petit
Divisions de pages lors d’insertion en masse1,2M84K93 % en moins
Scan séquentiel après insertion320 ms180 ms44 % plus rapide

Avec MySQL/InnoDB, l’impact est encore plus dramatique car la clé primaire EST l’index clusterisé — les UUID v4 aléatoires forcent une réorganisation constante des pages, tandis que v7 se comporte comme un auto-incrément.

Schémas d’identifiants alternatifs

ULID — Le champion d’avant v7

ULID (Universally Unique Lexicographically Sortable Identifier) a été créé en 2016 pour résoudre le problème de triabilité de UUID v4. Il encode un horodatage de 48 bits en millisecondes suivi de 80 bits d’aléatoire dans une chaîne Crockford Base32 de 26 caractères.

01AN4Z07BY      79KA1307SR9X4MV3
|----------|    |----------------|
 Horodatage        Aléatoire
   48 bits          80 bits

ULID vs UUID v7 — faut-il migrer ?

AspectULIDUUID v7
TriableOuiOui
Longueur de chaîne26 caractères36 caractères
Stockage16 octets16 octets
StandardSpécification communautaireIETF RFC 9562
Type DB natifNon (CHAR(26) ou BYTEA)Oui (uuid)
Support langagesnpm, PyPI, crates.ioIntégré dans la plupart des bibliothèques standard

Verdict : Pour un nouveau projet, utilisez UUID v7 — même triabilité avec un bien meilleur support écosystème et des types de base de données natifs. Si vous utilisez déjà ULID, pas besoin urgent de migrer ; les deux sont fonctionnellement équivalents.

Snowflake ID — Systèmes distribués à haut débit

Snowflake ID (créé par Twitter en 2010) empaquette un entier 64 bits avec :

0 | 41 bits horodatage | 10 bits worker ID | 12 bits séquence
  • 41 bits d’horodatage : millisecondes depuis une époque personnalisée (~69 ans de portée)
  • 10 bits de worker ID : supporte 1 024 workers uniques
  • 12 bits de séquence : jusqu’à 4 096 identifiants par milliseconde par worker

Points forts :

  • 8 octets — moitié de la taille d’UUID/ULID, se stocke dans une colonne BIGINT
  • Monotone au sein d’un worker — ordre garanti par nœud
  • Débit théorique de 4,096 millions d’ID/sec par worker
  • Lisible par l’humain en tant qu’entier simple

Points faibles :

  • Nécessite une coordination centrale — les worker ID doivent être attribués et gérés (typiquement via ZooKeeper, etcd ou un service de configuration)
  • Sensible au décalage d’horloge — si les horloges systèmes dérivent, les identifiants peuvent entrer en collision ou régresser
  • Époque personnalisée — chaque implémentation choisit sa propre époque, rendant l’interopérabilité inter-systèmes difficile
  • Pas de standard — des dizaines de variantes incompatibles (Twitter, Discord, Instagram, etc.)
// Génération Snowflake ID (avec sony/sonyflake)
package main

import (
    "fmt"
    "github.com/sony/sonyflake"
)

func main() {
    sf := sonyflake.NewSonyflake(sonyflake.Settings{})
    id, _ := sf.NextID()
    fmt.Println(id) // → 175928847299543040
}

Quand choisir Snowflake : votre système génère >100K identifiants/sec, vous avez besoin d’entiers compacts 64 bits, et vous disposez déjà d’une infrastructure pour l’attribution des worker ID (ex : ordinaux de pods Kubernetes).

NanoID — Identifiants compacts URL-safe

NanoID génère des identifiants courts (21 caractères par défaut) et URL-safe en utilisant l’alphabet A-Za-z0-9_-. Il utilise crypto.getRandomValues() pour la sécurité.

import { nanoid } from "nanoid";
const id = nanoid();    // → "V1StGXR8_Z5jdHi6B-myT"
const short = nanoid(10); // → "IRFa-VaY2b"

Idéal pour : les URL courtes, les clés de composants frontend, les codes d’invitation, les noms de fichiers — partout où la longueur de la chaîne compte et où vous n’avez pas besoin d’un tri au niveau base de données ni d’interopérabilité inter-systèmes.

Pas idéal pour : les clés primaires de base de données (pas de type DB natif, pas de triabilité, pas d’horodatage).

CUID2 — Résistance aux collisions à grande échelle

CUID2 génère des identifiants de longueur variable conçus pour la mise à l’échelle horizontale. Il intègre un compteur, un horodatage, une empreinte et de l’aléatoire.

Cas d’usage de niche : systèmes nécessitant une résistance aux collisions entre de nombreux générateurs indépendants sans coordination. En pratique, UUID v7 couvre ce besoin avec une meilleure standardisation.

Tableau comparatif complet

CaractéristiqueUUID v4UUID v7ULIDSnowflakeNanoID
Longueur36 car.36 car.26 car.15–20 chiffres21 car. (défaut)
Stockage16 octets16 octets16 octets8 octets~21 octets
TriableNonOui (temps)Oui (temps)Oui (temps)Non
HorodatageNon48 bits ms48 bits ms41 bits msNon
Aléatoire122 bits74 bits80 bits12 bits séq.~126 bits
StandardRFC 9562RFC 9562CommunautairePropriétaireCommunautaire
Type DB natifuuiduuidNonBIGINTNon
CoordinationAucuneAucuneAucuneRegistre workersAucune
URL-safeNon (tirets)Non (tirets)OuiOui (entier)Oui
Collision à 1M IDs~10⁻²²~10⁻¹⁸~10⁻²⁰Zéro (monotone)~10⁻²¹

Exemples de code : Génération de chaque type d’identifiant

JavaScript / TypeScript

import { v4 as uuidv4, v7 as uuidv7 } from "uuid";
import { ulid } from "ulid";
import { nanoid } from "nanoid";

// UUID v4
console.log(uuidv4());
// → "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"

// UUID v7
console.log(uuidv7());
// → "01906b5e-4a3e-7234-8f56-b8c12d4e5678"

// ULID
console.log(ulid());
// → "01ARZ3NDEKTSV4RRFFQ69G5FAV"

// NanoID
console.log(nanoid());
// → "V1StGXR8_Z5jdHi6B-myT"

Python

import uuid
from ulid import ULID
from nanoid import generate

# UUID v4
print(uuid.uuid4())
# → "a8098c1a-f86e-11da-bd1a-00112444be1e"

# UUID v7 (Python 3.14+ prévu, ou utilisez le package uuid7)
from uuid_extensions import uuid7
print(uuid7())
# → "01906b5e-4a3e-7234-8f56-b8c12d4e5678"

# ULID
print(ULID())
# → "01ARZ3NDEKTSV4RRFFQ69G5FAV"

# NanoID
print(generate(size=21))
# → "V1StGXR8_Z5jdHi6B-myT"

Go

package main

import (
    "fmt"

    "github.com/google/uuid"     // UUID v4 & v7
    "github.com/oklog/ulid/v2"   // ULID
    gonanoid "github.com/matoous/go-nanoid/v2" // NanoID
)

func main() {
    // UUID v4
    fmt.Println(uuid.New())
    // → "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"

    // UUID v7
    fmt.Println(uuid.Must(uuid.NewV7()))
    // → "01906b5e-4a3e-7234-8f56-b8c12d4e5678"

    // ULID
    fmt.Println(ulid.Make())
    // → "01ARZ3NDEKTSV4RRFFQ69G5FAV"

    // NanoID
    id, _ := gonanoid.New()
    fmt.Println(id)
    // → "V1StGXR8_Z5jdHi6B-myT"
}

Migration de UUID v4 vers v7

Si votre système utilise déjà des clés primaires UUID v4 et que vous souhaitez bénéficier des performances de v7, bonne nouvelle : v4 et v7 partagent le même format 128 bits et se stockent dans le même type de colonne uuid. Aucune migration de schéma nécessaire.

Stratégie de migration

  1. Les nouveaux enregistrements utilisent v7, les anciens gardent v4. Les deux coexistent dans la même colonne. Les requêtes et jointures fonctionnent de manière identique.
  2. Mettez à jour votre code de génération d’identifiants — remplacez uuidv4() par uuidv7() dans votre couche applicative.
  3. Ne réécrivez PAS les UUID v4 existants. Cela casserait les clés étrangères, les références externes et les URL mises en cache.
  4. Surveillez les performances d’index. À mesure que le ratio v4/v7 penche vers v7, la fragmentation de l’index diminuera progressivement.

Vérification de compatibilité

-- v4 et v7 coexistent dans la même colonne uuid
SELECT id, version FROM (
  SELECT id,
    CASE get_byte(id::bytea, 6) >> 4
      WHEN 4 THEN 'v4'
      WHEN 7 THEN 'v7'
      ELSE 'other'
    END AS version
  FROM your_table
) t
GROUP BY version;

Questions fréquentes

Faut-il utiliser UUID v7 ou des entiers auto-incrémentés ?

Les entiers auto-incrémentés sont plus simples et plus petits (4–8 octets vs 16 octets), mais nécessitent une séquence centralisée — seule la base de données peut les générer. UUID v7 peut être généré n’importe où (client, edge, microservice) sans aller-retour vers la base de données. Utilisez l’auto-incrément pour les applications simples à base de données unique ; utilisez UUID v7 pour les systèmes distribués, les architectures multi-tenant ou quand vous avez besoin de génération d’identifiants côté client.

Les 74 bits d’aléatoire de UUID v7 sont-ils suffisants ?

Oui. 74 bits d’aléatoire donnent 2⁷⁴ ≈ 1,9 × 10²² valeurs possibles par milliseconde. Même en générant 1 million d’identifiants par milliseconde, la probabilité de collision est d’environ 10⁻¹⁰ — bien en dessous de toute préoccupation pratique. Les 122 bits d’aléatoire de UUID v4 sont excessifs pour la plupart des applications.

Peut-on extraire l’horodatage d’un UUID v7 ?

Oui. Les 48 premiers bits encodent un horodatage Unix en millisecondes :

function extractTimestamp(uuidv7) {
  const hex = uuidv7.replace(/-/g, "").slice(0, 12);
  const ms = parseInt(hex, 16);
  return new Date(ms);
}

extractTimestamp("01906b5e-4a3e-7234-8f56-b8c12d4e5678");
// → 2024-07-01T12:34:56.000Z

C’est une fonctionnalité, pas un bug — mais si vous avez besoin d’identifiants opaques, utilisez v4.

PostgreSQL 18 supporte-t-il nativement UUID v7 ?

PostgreSQL 18 (publié en 2025) ajoute une fonction uuidv7() intégrée, éliminant le besoin d’extensions comme pgcrypto ou pg_uuidv7. MySQL ne dispose pas encore de génération v7 native — générez dans votre couche applicative.

Pourquoi ne pas simplement utiliser ULID ?

ULID est antérieur à UUID v7 et résout le même problème. Maintenant que v7 est un standard IETF (RFC 9562), il présente des avantages clés : type de base de données uuid natif (16 octets, indexation efficace), support plus large des langages/frameworks et standardisation formelle. Si vous utilisez déjà ULID, ça fonctionne très bien — pas besoin de migrer. Pour les nouveaux projets, préférez UUID v7.

Quand Snowflake ID est-il le meilleur choix ?

Quand vous avez besoin d’identifiants compacts 64 bits à un débit extrême (>100K ID/sec par nœud) et que vous disposez déjà d’une infrastructure pour l’attribution des worker ID. Le stockage BIGINT de 8 octets de Snowflake est la moitié de la taille d’UUID, ce qui compte à l’échelle de milliards de lignes. Le compromis est la complexité opérationnelle : vous devez gérer l’allocation des worker ID et gérer le décalage d’horloge.


Besoin de générer des UUID maintenant ? Essayez notre Générateur UUID — supporte v1, v4, v5 et v7 avec génération par lots et décodage, 100 % dans votre navigateur.

Articles connexes

Voir tous les articles