UUID v4 vs. v7: Welche Version sollten Sie verwenden?
UUID v4 vs v7 für Datenbank-Primary-Keys: warum v7 Inserts beschleunigt, wann v4 die Privatsphäre schützt und wie beide erzeugt werden.
Für einen neuen Datenbank-Primärschlüssel im Jahr 2026 ist UUID v7 die Standardwahl – zu v4 greifen Sie nur dann, wenn der Identifier öffentlich ist und sein Erstellungszeitpunkt privat bleiben muss.
Wenn Sie schon einmal beobachtet haben, wie die Insert-Latenz in einer stark beanspruchten Tabelle immer weiter ansteigt, und die Ursache auf einen Primärschlüssel zurückführen konnten, der jedes Mal in einer anderen Ecke des Index landet, wird Ihnen diese Frage vertraut vorkommen. Die Lösung ist deutlich kleiner als eine Schemamigration. Beide Formate sind 128-Bit-UUIDs, standardisiert im selben RFC – die Entscheidung hat also nichts mit Kompatibilität oder Kollisionssicherheit zu tun. Es kommt auf eine einzige Eigenschaft an: darauf, ob sich Ihre IDs in Erstellungsreihenfolge sortieren. Die zeitliche Ordnung von v7 behebt die Index-Fragmentierung, die zufällige v4-Schlüssel bei schreibintensiven Tabellen verursachen – zum Preis eines lesbaren Zeitstempels in jedem Wert. Dieser Leitfaden erläutert den strukturellen Unterschied, den Datenbankindex-Mechanismus hinter der Schreibperformance von v7, den Datenschutz-Trade-off, die aktuelle Bibliotheksunterstützung sowie eine klare Standardempfehlung.
Die wichtigsten Erkenntnisse
- UUID v4 und v7 sind beide 128-Bit- bzw. 16-Byte-Identifier, standardisiert in RFC 9562 (Mai 2024); v7 ersetzt die führenden 48 Bit durch einen Unix-Zeitstempel in Millisekunden, sodass sich die Werte in Erstellungsreihenfolge sortieren, während v4 vollständig zufällig ist.
- Zufällige v4-Schlüssel verteilen sich über den gesamten B-Tree-Index und führen zu Page Splits, Cache-Churn und Fragmentierung; das zeitlich geordnete Präfix von v7 bewirkt, dass Inserts nahe am Ende des Index angefügt werden – ein Verhalten, das einem sequenziellen Schlüssel sehr nahekommt.
- Eine v7-ID gibt ihren eigenen Erstellungszeitpunkt millisekundengenau preis; eine v4-ID nicht. Verwenden Sie v4 für öffentliche Identifier, Einladungslinks oder überall dort, wo Ihre Wachstumsrate nicht nach außen dringen soll.
- Die v7-Unterstützung ist erstklassig: PostgreSQL 18 bringt ein natives
uuidv7()mit, Python 3.14 hatuuid.uuid7()ergänzt, und das JavaScript-Paketuuid(v14.x) exportiertv7(). - Keine UUID ist ein Geheimnis: Verwenden Sie für die Authentifizierung ein dediziertes 256-Bit-Zufallstoken und beschränken Sie UUIDs auf die Identifikation.
Was ist der Unterschied zwischen UUID v4 und v7?
UUID v4 und v7 sind beide 128-Bit- bzw. 16-Byte-Identifier, standardisiert in RFC 9562, das im Mai 2024 als Standards-Track-Dokument veröffentlicht wurde und das ältere RFC 4122 ersetzt. Der einzige strukturelle Unterschied liegt darin, woher die Bits kommen. UUID v4 besteht aus 122 Zufallsbits, wobei 6 Bit für Versions- und Variantenmarker reserviert sind – dadurch ist sie vollständig zufällig und unsortiert. UUID v7 ersetzt die führenden 48 Bit durch einen Unix-Zeitstempel in Millisekunden und füllt die verbleibenden ca. 74 Bit mit Zufallswerten (zuzüglich der Versions- und Variantenmarker). Dadurch sortieren sich v7-Werte lexikalisch und byteweise in Erstellungsreihenfolge, v4-Werte hingegen nicht.
UUID v4: [ 122 random bits ...................... ] + version/variant
UUID v7: [ 48-bit ms timestamp ][ ~74 random bits ] + version/variant
Diese einzige Änderung macht die gesamte Entscheidung aus. Beide behalten dieselbe Kollisionsmathematik aus dem Zufallsanteil, beide passen in dieselbe Spalte, und beide sind durch denselben Standard abgedeckt.
Discover how at OpenReplay.com.
Warum ist UUID v7 die bessere Wahl für Datenbankschlüssel?
v7 übertrifft v4 als Primärschlüssel, weil das Zeitstempel-Präfix den Inserts eine Index-Lokalität verschafft, die zufällige Schlüssel zerstören. Zufällige v4-Schlüssel landen an beliebigen Positionen in einem B-Tree-Index und verursachen Page Splits, Cache-Churn und Fragmentierung, da jeder Insert einen anderen Teil des Baums adressiert. Genau dieses Problem nennt RFC 9562 als Begründung für die Definition von v7: Tragen Identifier keine zeitliche Ordnung, muss jede neue Zeile dort geschrieben werden, wo ihr Zufallswert gerade hinfällt – während Werte, die unter einem zeitlich geordneten Schema nacheinander erzeugt werden, im Index als Nachbarn landen. Das monotone Präfix von v7 bedeutet, dass neue Zeilen nahe am Ende des Index angefügt werden. Page Splits werden dadurch selten und der Insert-Durchsatz nähert sich dem eines sequenziellen Integer-Schlüssels – bei gleichzeitiger Beibehaltung der UUID-Kollisionssicherheit und der verteilten Generierung.
Am stärksten fällt die Strafe bei Engines mit Clustered Index aus. In MySQL InnoDB und SQL Server ist die Tabelle physisch nach dem Primärschlüssel geordnet, sodass zufällige Inserts Pages in der gesamten Struktur neu schreiben. PostgreSQL speichert Zeilen in einem Heap mit separaten Indizes und ist damit weniger empfindlich gegenüber der Zufälligkeit des Schlüssels – doch auch dort verlieren die Indizes bei zufälligen v4-Schlüsseln an Cache-Lokalität. Das Ausmaß hängt von Engine, Workload und Hardware ab. Betrachten Sie konkrete Prozentangaben aus Blog-Benchmarks ohne Quellenangabe daher skeptisch und messen Sie an Ihrer eigenen Tabelle. Der Mechanismus selbst ist unstrittig.
Die zeitliche Ordnung hält auch bei Burst-Inserts. Implementierungen ergänzen einen Sub-Millisekunden-Zähler, damit IDs, die innerhalb derselben Millisekunde erzeugt werden, weiterhin korrekt sortieren: Pythons uuid.uuid7() reserviert 42 Bit als Zähler, sodass Werte innerhalb einer einzelnen Millisekunde ihre Reihenfolge beibehalten, und uuidv7() in PostgreSQL 18 setzt jeden Wert aus einem Unix-Zeitstempel in Millisekunden, einem Sub-Millisekunden-Anteil und Zufallsbits zusammen.
Wann UUID v4 nach wie vor die richtige Wahl ist
Wählen Sie v4, wenn die ID nach außen sichtbar ist und ihr Erstellungszeitpunkt sensibel ist – denn eine v7-ID enthält ihren eigenen Erstellungszeitpunkt millisekundengenau. Wer die ID lesen kann, kann auch ablesen, wann der Datensatz angelegt wurde. Damit eignet sich v7 schlecht für nach außen sichtbare Identifier. Das Aiven-Team kommt zum selben Ergebnis: Sobald ein Primärschlüssel über eine externe App oder API an Endnutzer weitergegeben wird, ist v7 keine sinnvolle Wahl mehr, weil der Identifier verrät, wann der Datensatz erstellt wurde. Verwenden Sie v4 für Einladungstokens, Share-Links oder überall dort, wo ein Mitbewerber aus ID-Bereichen auf Ihre Wachstumsrate schließen könnte.
Eine Einschränkung gilt für beide Versionen: Keine UUID ist ein Sicherheitstoken. Die nicht-zufälligen Bits in v7 sind vorhersagbar, und die Qualität der Zufälligkeit von v4 ist implementierungsabhängig – keine von beiden sollte daher eine Authentifizierung absichern. Erzeugen Sie für Secrets eine dedizierte, kryptografisch zufällige Zeichenkette mit mindestens 256 Bit und nutzen Sie UUIDs ausschließlich zur Identifikation.
v7 heute erzeugen und schrittweise migrieren
Die v7-Unterstützung ist inzwischen über Datenbanken und Sprachen hinweg breit verfügbar, wobei die genaue Version entscheidend ist:
| Plattform | v7-Generierung | Version |
|---|---|---|
| PostgreSQL | uuidv7() (native) | PostgreSQL 18 |
| Python | uuid.uuid7() (Standardbibliothek) | Python 3.14 |
| JavaScript / Node | v7() aus uuid | uuid v14.x |
PostgreSQL 18 hat uuidv7() als native Funktion eingeführt und zusätzlich einen uuidv4()-Alias für das bestehende gen_random_uuid() ergänzt; unter PostgreSQL 17 und älter benötigen Sie eine Extension oder eine Bibliothek auf Anwendungsseite. Python hat uuid.uuid7() in Version 3.14 in die Standardbibliothek aufgenommen – nicht in 3.12, wo der Aufruf einen AttributeError auslöst. In JavaScript stellt das uuid-Paket v7 über einen benannten ESM-Import bereit; laut Changelog hat das Paket die CommonJS-Unterstützung in v12 eingestellt:
// Node.js, uuid v14.x
import { v7 as uuidv7 } from "uuid";
const id = uuidv7();
-- PostgreSQL 18
SELECT uuidv7();
Wenn Sie den Unterschied sehen möchten, bevor Sie sich auf einen Spaltentyp festlegen, erzeugen Sie jeweils einen Stapel und stellen Sie sie gegenüber. Der UUID-Generator von OpenReplay erzeugt v4- oder v7-Werte direkt im Browser, bis zu 500 auf einmal, mit Schaltern für Großschreibung, Ausgabe ohne Bindestriche und Ausgabe in Anführungszeichen – so können Sie die Werte direkt in SQL oder ein JSON-Fixture einfügen. Sortieren Sie eine Spalte mit v7-Werten, erscheinen sie in Erstellungsreihenfolge; machen Sie dasselbe mit v4, verteilen sie sich beliebig. Die Werte stammen aus der Web Crypto API in Ihrem eigenen Browser-Tab, keiner von ihnen wird irgendwohin übertragen.
Die Migration erfordert kein Umschreiben. v4 und v7 verwenden denselben 16-Byte-uuid-Spaltentyp – Sie können bestehende v4-Zeilen also beibehalten und neue Zeilen in derselben Tabelle als v7 erzeugen. Die Version ist im Wert selbst kodiert, ein Backfill ist nicht erforderlich. Neue Inserts sammeln sich am Ende des Index, und die Fragmentierung nimmt allmählich ab, während Pages im Laufe der Zeit neu geschrieben werden; das ist ein fortschreitender Effekt, keine sofortige Defragmentierung.
Das Fazit: Welche Version sollten Sie verwenden?
Setzen Sie UUID v7 als Standard für neue Datenbank-Primärschlüssel, Logs und Event-Streams ein; wählen Sie v4, wenn Unvorhersehbarkeit entscheidend ist. v7 liefert Ihnen die Schreibperformance eines sequenziellen Schlüssels bei gleichzeitiger Kollisionssicherheit und verteilter Generierung einer UUID – und wird inzwischen von den Plattformen, die die meisten Teams ohnehin betreiben, nativ unterstützt. Reservieren Sie v4 für Identifier, die öffentlich sind und bei denen der Erstellungszeitpunkt privat bleiben muss.
Zwei Alternativen runden die Entscheidung ab. ULID kodiert dieselbe Idee aus Zeitstempel plus Zufallsanteil in Crockford-Base32 und ergibt so eine kürzere, URL-freundliche Zeichenkette mit 26 Zeichen – ist jedoch kein IETF-Standard und verfügt über keinen nativen uuid-Spaltentyp. Ein einfaches bigint mit Auto-Increment bleibt die kleinste und schnellste Option für ein kleines Single-Node-System, das nie eine verteilte ID-Generierung benötigen wird.
Wenn Sie heute eine neue Tabelle aufsetzen und die Index-Probleme durch v4-Schlüssel spüren: Stellen Sie neue Inserts auf v7 um, lassen Sie Ihre alten Zeilen unverändert und geben Sie dem Index Zeit, sich zu beruhigen. Der Gewinn ist praktisch ohne Migrationsaufwand zu haben.
FAQs
Lässt sich der Erstellungszeitstempel aus einem UUID-v7-Wert extrahieren?
Ja. Da UUID v7 einen 48-Bit-Unix-Zeitstempel in Millisekunden in seinen führenden Bits speichert, lässt sich dekodieren, wann der Wert erzeugt wurde. PostgreSQL 18 stellt genau dafür uuid_extract_timestamp() bereit, das um die Unterstützung von Version-7-Werten erweitert wurde. Das ist ein Vorteil für Debugging und Zeitbereichsabfragen, aber auch der Grund, weshalb v7 den Erstellungszeitpunkt preisgibt und nicht für öffentliche Identifier verwendet werden sollte, wenn dieser Zeitpunkt sensibel ist.
Haben UUID v7 und v4 dasselbe Kollisionsrisiko?
Nein, aber der Unterschied ist in der Praxis vernachlässigbar. UUID v4 enthält 122 Zufallsbits, während v7 nach den 48 Bit für den Zeitstempel sowie den Versions- und Variantenmarkern etwa 74 Zufallsbits behält. v7 hat also weniger Zufallsbits, doch Kollisionen sind ausschließlich zwischen IDs möglich, die innerhalb derselben Millisekunde erzeugt werden – und Implementierungen ergänzen innerhalb dieses Zeitfensters einen monotonen Zähler. Für reale Workloads sind beide bei jeder realistischen Erzeugungsrate praktisch kollisionsfrei.
Verbessert UUID v7 die Performance von Leseabfragen oder nur die von Inserts?
v7 verbessert vor allem die Schreibperformance und Range Scans, indem Zeilen im Index nahe beieinander angeordnet werden, was Page Splits reduziert und die Cache-Lokalität verbessert. Schreiben Sie große Lesegeschwindigkeitsgewinne nicht allein v7 zu. Die offiziell für PostgreSQL 18 genannte Leseverbesserung von 'bis zu 3x' stammt aus dem neuen asynchronen I/O-Subsystem, einem von uuidv7() unabhängigen Feature. Der korrekte Wirkungsbereich des Performancevorteils von v7 sind Index-Lokalität und Insert-Durchsatz.
Sollte ich bestehende UUID-v4-Primärschlüssel auf v7 migrieren?
In der Regel ist keine vollständige Migration nötig. v4 und v7 verwenden denselben 16-Byte-uuid-Spaltentyp und die Version ist im Wert kodiert – Sie können bestehende v4-Zeilen also unangetastet lassen und neue Zeilen in derselben Tabelle ohne Backfill als v7 erzeugen. Neue Inserts sammeln sich am Ende des Index, und die Fragmentierung nimmt allmählich ab, während Pages neu geschrieben werden. Ein Umschreiben alter Zeilen lohnt sich nur, wenn die Fragmentierung bereits messbare Probleme verursacht.