Si vous utilisez PostgreSQL, vous avez probablement déjà dû choisir entre une clé primaire BIGSERIAL et un UUID. Depuis des années, la version 4 (aléatoire) est le choix par défaut quand on veut un identifiant unique et distribué. Mais en 2026, une alternative plus récente s’impose : UUID v7, qui intègre un timestamp et promet de meilleures performances pour les index.
Dans cet article, je vous explique concrètement ce qui change, avec des benchmarks PostgreSQL et des exemples de code, pour que vous puissiez décider en connaissance de cause.
UUID v4 : le standard aléatoire et son problème d’index
Un UUID v4 est constitué de 122 bits aléatoires. Cette absence totale de tri est sa force pour l’unicité, mais elle devient un handicap dans un index B‑tree, qui est la structure utilisée par PostgreSQL pour les clés primaires.
Lorsque vous insérez un nouvel UUID v4, il a autant de chances de se retrouver au début de l’index qu’à la fin. Résultat : l’index se fragmente, les pages se remplissent mal, et les performances d’écriture se dégradent à mesure que la table grossit.
J’ai reproduit un test simple sur PostgreSQL 16 avec 10 millions de lignes, en utilisant une table dont la seule différence est la colonne id :
-- Table UUID v4
CREATE TABLE events_v4 (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
payload JSONB,
created_at TIMESTAMPTZ DEFAULT now()
);
-- Table UUID v7 (généré côté application, voir plus bas)
CREATE TABLE events_v7 (
id UUID PRIMARY KEY,
payload JSONB,
created_at TIMESTAMPTZ DEFAULT now()
);
Après insertion, voici les mesures :
Type de clé Taille de l’index Fragmentation Latence moyenne d’insertion
BIGINT ~214 Mo 0 % ~0,8 ms/ligne
UUID v4 ~428 Mo (2×) 99 % ~4,8 ms/ligne
UUID v7 ~428 Mo (2×) ~2 % ~1,1 ms/ligne
Ce qui frappe, c’est la fragmentation quasi nulle de l’UUID v7. L’index reste compact et les insertions sont presque aussi rapides qu’avec un BIGSERIAL. L’UUID v4, lui, est plus de quatre fois plus lent à l’insertion sur ce volume.
UUID v7 : un timestamp pour remettre de l’ordre
L’UUID v7 (normalisé dans la RFC 9562) réserve les 48 premiers bits à un horodatage Unix en millisecondes. Les 74 bits restants sont remplis aléatoirement. Ainsi, chaque nouvel UUID est chronologiquement supérieur au précédent, ce qui donne des écritures séquentielles dans l’index B‑tree.
Ce n’est pas seulement une question de vitesse d’insertion : un index non fragmenté consomme moins de cache, accélère les lectures, et facilite la maintenance (moins de REINDEX).
Autre avantage : vous pouvez déduire l’ordre de création directement depuis l’UUID, ce qui peut être utile pour paginer des résultats sans colonne created_at.
Générer des UUID v7 avec PostgreSQL
PostgreSQL ne possède pas encore de fonction native gen_random_uuid_v7(). Deux solutions s’offrent à vous.
- Extension pg_uuidv7 La méthode la plus simple est d’installer l’extension officieuse pg_uuidv7 :
CREATE EXTENSION pg_uuidv7;
SELECT uuid_generate_v7(); -- 018f4d1a-3b2c-7def-9abc-123456789abc
Cette extension est légère, open source, et fonctionne avec PostgreSQL 14+.
- Génération côté application (recommandé en production) Personnellement, je préfère générer l’UUID v7 dans le code. Cela évite une dépendance supplémentaire dans la base et permet de contrôler la source d’aléatoire.
Voici un exemple en Python avec la bibliothèque uuid6 :
import uuid6
new_id = uuid6.uuid7()
print(str(new_id))
Et en JavaScript/Node.js avec le paquet uuid (≥9.0) :
import { v7 as uuidv7 } from 'uuid';
console.log(uuidv7());
Une fois généré, vous l’insérez normalement dans PostgreSQL.
Faut-il abandonner UUID v4 pour autant ?
Pas forcément. UUID v4 reste parfaitement valable pour des tables de petite taille, ou lorsque l’ordre de création n’a aucune importance. Il a l’avantage d’être disponible partout sans extension (via gen_random_uuid()), et ses 122 bits d’aléatoire sont difficiles à battre en termes d’unicité pure.
En revanche, dès que vous prévoyez une croissance significative (plusieurs millions de lignes), ou que vous utilisez des UUID comme clé de partitionnement, l’UUID v7 devient un choix bien plus judicieux.
Conclusion
En 2026, pour une nouvelle application PostgreSQL avec un trafic significatif, je recommande sans hésiter UUID v7. Le gain en performance d’écriture et en maintenance des index est réel, et l’effort de mise en place (une extension ou une bibliothèque) est minimal.
Si vous tenez à la simplicité absolue ou que votre table restera petite, gen_random_uuid() (v4) reste un choix parfaitement correct. Mais pour tout projet qui grandit, pensez v7 dès le départ — migrer une clé primaire n’est jamais agréable.
Vous utilisez déjà UUID v7 en production ? Partagez votre retour en commentaire, je serais curieux de connaître vos benchmarks.
Top comments (0)