Comparison
UUID v4 vs v7 : choisissez v7 pour les clés de base de données
v4 pour les jetons opaques. v7 pour tout le reste, surtout les clés de base de données.
By Buğra SözeriPublished
En bref.UUID v4 représente 122 bits d’aléatoire pur et n’est pas triable, ce qui détruit les performances d’index B-tree quand il est utilisé comme clé de base de données. UUID v7 (RFC 9562, 2024) ajoute un horodatage Unix de 48 bits en millisecondes pour que les identifiants soient triés par ordre de création. Utilisez v7 pour les clés de base de données et les identifiants d’événements ; gardez v4 pour les jetons de session opaques.
Les UUID sont des identifiants de 128 bits conçus pour être globalement uniques entre systèmes sans coordination. La spécification originale (RFC 4122, 2005) définissait cinq versions ; v4 (purement aléatoire) était la seule que la plupart des développeurs utilisaient. RFC 9562 (2024) a ajouté v7, et v7 devrait être le nouveau défaut pour presque tous les cas d’usage où v4 était précédemment choisi.
Les différences essentielles
| Propriété | v4 | v7 |
|---|---|---|
| Spécifié | RFC 4122 (2005) | RFC 9562 (2024) |
| Bits aléatoires | 122 | 74 |
| Horodatage intégré | Non | Oui (48 bits ms depuis epoch) |
| Triable par date de création | Non (purement aléatoire) | Oui (lexicographique = chronologique) |
| Probabilité de collision | ~1 sur 10³⁶ pour toute paire | Pratiquement nulle (horodatage + aléatoire combinés) |
| Compatibilité index de base de données | Mauvaise (insertion aléatoire dégrade les B-trees) | Excellente (séquentielle, compatible ajout) |
| Support navigateur | crypto.randomUUID() depuis 2021 | Génération manuelle (pas encore d’API native) |
Pourquoi v4 nuit aux bases de données
Les clés primaires de base de données résident typiquement dans un index B-tree. Les B-trees fonctionnent mieux quand les insertions arrivent dans l’ordre trié : les nouvelles clés s’ajoutent à la feuille la plus à droite, aucun rééquilibrage nécessaire, la page d’index reste chaude dans le cache.
Les clés aléatoires (v4) détruisent tout cela. Chaque insertion atterrit dans une page aléatoire, causant potentiellement une division de page, certainement des défauts de cache, et produisant de l’espace libre dispersé dans l’index qui ne sera jamais compacté. Pour les charges de travail à forte écriture, cela se manifeste par :
- 10 à 100× plus d’E/S que les clés séquentielles au même taux d’écriture
- Fichiers d’index gonflés (souvent 2 à 3× la taille qu’ils auraient avec des clés triées)
- Ralentissements des requêtes à mesure que le taux de succès du cache se dégrade
Les benchmarks Postgres-vs-MySQL comparant UUID v4 aux clés primaires bigint montrent systématiquement un débit d’écriture 2 à 5× supérieur sur des charges de travail représentatives. La solution n’est pas d’abandonner les UUID — c’est d’utiliser le type d’UUID qui se trie.
À quoi ressemble v7
Un UUID v7 :
01950d29-4f6f-7234-bf01-a8b3c0d9e102 └─────timestamp_ms──────┘ └──aléatoire──┘
48 premiers bits : horodatage Unix en millisecondes (valable jusqu’à ~10889 apr. J.-C.). 4 bits suivants : version (toujours 7). 12 bits suivants : aléatoire. Ensuite 2 bits de marqueur de variante + 62 bits d’aléatoire. Total aléatoire : 74 bits — résistance aux collisions amplement suffisante.
Deux UUID v7 créés dans la même milliseconde sont en compétition sur les 74 bits d’aléatoire ; la probabilité de collision dans cette milliseconde est d’environ 10⁻²² pour un système à milliard d’identifiants. Entre les millisecondes, l’horodatage rend les collisions structurellement impossibles.
Quand v4 est encore le bon choix
- Jetons de session opaquesoù vous ne voulez pas que l’ordre de création soit divulgué. v7 divulgue des horodatages de création à résolution ~milliseconde dans le préfixe, ce qui convient aux clés de base de données mais est mauvais pour les jetons sensibles à la vie privée.
- Clés API, jetons d’accès, jetons de réinitialisation de mot de passe: l’opacité compte plus que la triabilité.
- Identifiants d’anonymisation: où observer l’horodatage aiderait un attaquant à corréler.
Quand v7 est clairement meilleur
- Clés primaires de base de données.
- Identifiants de système distribué (identifiants d’événements, de commandes, de traces).
- Partout où vous bénéficieriez d’un ORDER BY id donnant un ordre chronologique gratuit.
- Partout où des requêtes par plage sur la date de création nécessiteraient autrement un index séparé sur created_at.
Le chemin de migration
Nouvelles tables : utilisez v7 dès le départ. Anciennes tables : généralement pas la peine de migrer, mais si vous atteignez des plafonds de débit d’écriture sur une table avec clé UUID, passer à v7 est un changement structurel valable.
Générez l’un ou l’autre via notre générateur UUID, qui prend en charge les deux versions.
Chiffres clés
- Longueur de chaîne : les deux font 36 caractères avec tirets (32 hex + 4 tirets), 32 caractères sans tirets, 22 caractères en base64url, 16 octets bruts.
- Entropie : v4 a 122 bits aléatoires (6 bits consommés par les marqueurs de version + variante) ; v7 a 74 bits aléatoires après l’horodatage de 48 bits.
- Calcul de collision v4 : probabilité de collision de 50 % après avoir généré ~2⁶¹ ≈ 2,3 × 10¹⁸ UUID — générez un milliard par seconde et vous attendriez ~85 ans.
- Plage d’horodatage v7 : le champ Unix-milliseconde de 48 bits couvre l’année 1970 à l’année 10889.
- Benchmark B-tree Postgres (Percona, 2023) : ~7 000 insertions/sec avec v4 contre ~28 000 insertions/sec avec v7/ULID sur le même matériel et schéma — un écart de 4× qui s’élargit à mesure que l’index dépasse la RAM.
- Gonflement d’index : une table de 100 M lignes avec clé v4 finit couramment 2 à 3× plus grande sur disque que les mêmes données avec clé v7 ou bigint séquentiel, à cause de l’espace libre laissé après les divisions de pages.
- Vitesse de génération :
crypto.randomUUID()(v4) tourne à ~3 M ops/sec dans Node 20 ; les implémentations v7 (uuid v9, ulid) atteignent ~2,5 M ops/sec.
Matrice de décision
| Cas d’usage | Choisir |
|---|---|
| Clé primaire Postgres / MySQL | v7 (ou ULID) |
| Identifiant d’événement distribué, de trace, de commande | v7 |
| Jeton de session, jeton CSRF | v4 (l’opacité compte) |
| Jeton de réinitialisation de mot de passe / lien magique | v4 + TTL court |
| Préfixe de clé API | v4 |
| Clé d’objet S3 (liste triable) | v7 |
| Clé d’idempotence dans la livraison de webhook | v7 (ordre chronologique pratique pour le débogage) |
| Slug public | Ni l’un ni l’autre — utilisez NanoID ou hash court |
Sources
- RFC 9562 — Universally Unique IDentifiers (UUIDs), mai 2024 — rfc-editor.org/rfc/rfc9562 (définit v6, v7, v8 ; remplace RFC 4122).
- Blog Percona — UUIDs in Databases: A Deep Dive, benchmarks v4 vs clés séquentielles — percona.com.
Frequently asked questions
- UUID v7 est-il rétrocompatible avec v4 ?
- Oui — les deux sont des identifiants de 128 bits dans le même format hex 8-4-4-4-12, les deux s’insèrent dans n’importe quelle colonne ou API qui accepte un UUID v4, et les deux encodent leur version dans le même quartet. La migration concerne uniquement la façon dont vous générez les nouveaux identifiants ; les v4 existants dans la base de données continuent de fonctionner sans modification.
- v7 révèle-t-il l’horodatage de création ?
- Oui — les 48 premiers bits sont l’horodatage Unix en millisecondes, lisible par quiconque voit l’UUID. Pour la plupart des clés de base de données, c’est acceptable ou même utile, mais pour les jetons de session opaques ou les codes de réinitialisation de mot de passe où vous ne voulez pas exposer l’ordre de création, restez avec v4.
- Pourquoi v4 nuit-il aux performances de la base de données ?
- Parce que les clés aléatoires atterrissent dans des pages aléatoires d’un index B-tree à chaque insertion, causant des divisions de pages et détruisant la localité du cache. Les clés séquentielles (comme le préfixe d’horodatage de v7) s’ajoutent à la feuille la plus à droite et restent compatibles avec le cache. Les benchmarks Postgres et MySQL montrent typiquement un débit d’écriture 2 à 5 fois supérieur.
- Puis-je générer des UUID v7 dans le navigateur ?
- Pas nativement encore — crypto.randomUUID() retourne v4. Vous avez besoin d’une petite bibliothèque (uuid v9+, polyfills basés sur ulid) ou de 10 lignes de code combinant Date.now() avec crypto.getRandomValues(). Le support natif de v7 est sur la feuille de route WHATWG.
Related
Published May 15, 2026