uuidv7 | rfc 9562 | tidssorterbar

> uuidv7 generator <

// Tidsordnede, sorterbare UUID'er (RFC 9562, 2024) — 48-bit Unix-ms-tidsstempel + 74 tilfældige bit, genereret lokalt

// AFKOD / INSPICÉR EN UUIDV7

Indsæt enhver UUID nedenfor for at udtrække dens indlejrede tidsstempel, version og variant. Virker med v7 og rapporterer, hvis input er en anden UUID-version.

Tidsstempel (ms): // afkodede felter vises her
ISO 8601 UTC: // afkodede felter vises her
Alder: // afkodede felter vises her
Version: // afkodede felter vises her
Variant: // afkodede felter vises her
rand_a (12-bit): // afkodede felter vises her
rand_b (62-bit): // afkodede felter vises her
[RFC 9562]

Specifikationsoverensstemmende UUIDv7

Implementerer det tidsordnede UUID-format fra RFC 9562 (maj 2024): 48-bit Unix-millisekund-tidsstempel, 4-bit version 7, 12-bit rand_a, 2-bit variant, 62-bit rand_b. Verificeret mod specifikationens testvektorer.

[SORTABLE]

Kronologisk sorteringsrækkefølge

Sortér numerisk eller leksikografisk, og du får indsættelsesrækkefølgen — perfekt til B-træ-primærnøgler, tidsserieindekser og logkorrelation. Ikke flere tilfældige v4-sideopdelinger eller fragmenterede indekser.

[MONOTONIC]

Monotoni inden for samme millisekund

Når flere UUID'er falder i ét millisekund, øges den tilfældige del strengt, så outputtet forbliver sorteret inden for det ms. Slå fra for ren RFC 9562 Metode 1 (tilfældig fyld), hvis du foretrækker det.

[DECODER]

Inspicér enhver UUIDv7

Indsæt en v7-UUID, og afkoderen udtrækker det indlejrede tidsstempel (ms + ISO 8601), versionsbit, variantbit og felterne rand_a / rand_b. Nyttigt til fejlfinding, logarkæologi og revisionsspor.

// OM UUIDV7

Sådan virker UUIDv7:

En UUIDv7 er en 128-bit identifikator opbygget som unix_ts_ms (48) | ver (4) | rand_a (12) | var (2) | rand_b (62). De første 48 bit er det aktuelle Unix-tidsstempel i millisekunder, big-endian, hvilket gør UUID'en monotont stigende i tid. De næste 4 bit koder versionen (binært 0111 = decimal 7), så den tredje bindestregsadskilte gruppe altid begynder med cifferet 7. rand_a er 12 tilfældige bit brugt til sub-millisekund-opløsning eller som ekstra entropi. Det 2-bit variantfelt er fastsat til 10 (så det første tegn i den fjerde gruppe altid er 8, 9, a eller b). De resterende 62 bit (rand_b) kommer fra crypto.getRandomValues() ved hver generering. Den samlede entropi pr. UUID er 74 tilfældige bit, hvilket er kollisionsbestandigt for enhver realistisk genereringshastighed.

Eksempel:

018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55 (ts=2024-05-08T15:00:00.000Z)

Standarder og referencer:

  • >RFC 9562 — Universally Unique IDentifiers (UUIDs), maj 2024 (forælder RFC 4122, definerer v6/v7/v8)
  • >RFC 4122 — den oprindelige UUID-specifikation fra 2005 (stadig autoritativ for v1-v5)
  • >Web Crypto API (W3C) — crypto.getRandomValues() CSPRNG brugt til de 74 tilfældige bit
  • >PostgreSQL gen_random_uuid()-adfærd (v4 som standard, v7 i pgcrypto-udvidelser / forks)
  • >draft-peabody-dispatch-new-uuid-format — det oprindelige v6/v7/v8-forslag, der blev til RFC 9562

Hvorfor bruge UUIDv7:

  • >Databaseprimærnøgler med indsættelseslokalitet — sider forbliver pakkede, indekser fragmenterer ikke
  • >Erstatter et par af sekvens + UUID: én kolonne, sorterbar OG globalt unik
  • >Erstatter v4-primærnøgler i skrivetunge tabeller for at løse problemet med sideopdeling ved tilfældig indsættelse
  • >Logkorrelations-id'er, der sorterer efter oprettelsestid uden en separat tidsstempelkolonne
  • >Distribuerede systemer, hvor flere skrivere har brug for ordnede id'er uden en koordinator
  • >Event sourcing / append-only-logs, hvor kronologisk rækkefølge er det naturlige indeks
  • >S3- / objektlagernøgler, hvor præfikssortering matcher indsættelsesrækkefølgen
  • >Erstatter Snowflake / KSUID / ULID, hvor et standardformat er at foretrække

Relaterede værktøjer:

  • >UUID-generator — genererer v4 (tilfældig) og v1 (tidsstempel), når du ikke har brug for v7's sorteringsrækkefølge
  • >GUID-generator — samme identifikator under Microsoft-navngivningen
  • >Tidsstempelkonverter — konverterer de indlejrede Unix-ms tilbage til lokal tid / ISO 8601
  • >Epoch-konverter — inspicér 48-bit-tidsstempeldelen i enhver tidszone
  • >Adgangskodegenerator — kryptografisk tilfældige tokens, når sorterbarhed ikke er påkrævet

// EKSEMPEL-OUTPUT

Enkelt UUIDv7 genereret nu

config: count=1, format=standard, timestamp=current

output:

018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55

Massebatch med monotoni i samme millisekund

config: count=5, format=standard, monotonic=on

output:

018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55
018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a56
018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a57
018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a58
018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a59

Brugerdefineret historisk tidsstempel — udfyldning af en migrering

config: count=1, timestamp=custom, value=1577836800000 (2020-01-01)

output:

016f5e66-e800-7c9a-b403-2f1d4a7c91ee

Kompakt format til URL'er / filnavne

config: count=1, format=no-hyphens

output:

018f5c2e90c07a4fb6ee8dfe3c2b0a55

Afkodet UUIDv7 — inspicér de indlejrede felter

config: input = 018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55

output:

ts_ms = 1715180400000
ISO   = 2024-05-08T15:00:00.000Z
ver   = 7
var   = 10 (RFC 4122)
rand_a = 0xa4f
rand_b = 0x36ee8dfe3c2b0a55

// IMPLEMENTÉR DET SELV

De fleste sprog har enten en stdlib-hjælper eller en implementering i én fil til UUIDv7, siden RFC 9562 udkom i 2024. Nedenfor er de kanoniske opskrifter, du kan indsætte i din kodebase — i browser-JS, Node.js, Go, Python og PostgreSQL.

[JavaScript]

UUIDv7 i ren browser-/Node-JS — RFC 9562-opbygning

function uuidv7() {
  const ts = BigInt(Date.now());
  const rand = new Uint8Array(10);
  crypto.getRandomValues(rand);
  const b = new Uint8Array(16);
  b[0] = Number((ts >> 40n) & 0xFFn);
  b[1] = Number((ts >> 32n) & 0xFFn);
  b[2] = Number((ts >> 24n) & 0xFFn);
  b[3] = Number((ts >> 16n) & 0xFFn);
  b[4] = Number((ts >> 8n)  & 0xFFn);
  b[5] = Number( ts          & 0xFFn);
  b[6] = (rand[0] & 0x0F) | 0x70;   // version = 7
  b[7] =  rand[1];
  b[8] = (rand[2] & 0x3F) | 0x80;   // variant = RFC 4122
  for (let i = 9; i < 16; i++) b[i] = rand[i - 6];
  const h = Array.from(b, x => x.toString(16).padStart(2,'0')).join('');
  return `${h.slice(0,8)}-${h.slice(8,12)}-${h.slice(12,16)}-${h.slice(16,20)}-${h.slice(20)}`;
}

// usage:
const id = uuidv7();
console.log(id);   // -> '018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55'

// generate a batch and verify chronological sort:
const batch = Array.from({ length: 5 }, uuidv7);
batch.sort();      // sorts by creation time without a separate timestamp
[Node.js]

Node.js v26.1.0+ — indbygget crypto.randomUUIDv7()

import { randomUUIDv7 } from 'node:crypto';

// Added in Node.js v26.1.0 (2026-05-07).
// Returns an RFC 9562 version 7 UUID. The first 48 bits encode a
// millisecond Unix timestamp; the rest is CSPRNG output.
const id = randomUUIDv7();
// -> '018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55'

// The CSPRNG output is cached for performance: Node generates enough
// entropy upfront for the next ~128 UUIDs. Pass disableEntropyCache: true
// when you need each call to draw fresh randomness, e.g. directly after
// a fork() or in tight high-security loops.
const freshId = randomUUIDv7({ disableEntropyCache: true });

// IMPORTANT: per the Node docs, "the embedded timestamp relies on a
// non-monotonic clock and is not guaranteed to be strictly increasing."
// If two UUIDs land in the same millisecond OR the system clock steps
// backwards, the IDs may not sort in creation order. Use a userland
// monotonic-v7 library (e.g. uuidv7 on npm) when strict ordering matters.
[Go]

Go — google/uuid v1.6+ leverer UUIDv7 nativt

package main

import (
    "fmt"
    "github.com/google/uuid"
)

func newID() uuid.UUID {
    id, err := uuid.NewV7()
    if err != nil {
        panic(err)
    }
    return id
}

func main() {
    id := newID()
    fmt.Println(id.String())  // 018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55
    fmt.Println(id.Time())    // embedded creation timestamp
}
[Python]

Python 3.13+ — stdlib uuid.uuid7()

import uuid

# Python 3.13 added uuid7() and uuid8() to the standard library.
uid = uuid.uuid7()
print(uid)            # 018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55
print(uid.version)    # 7

# For older Python use the 'uuid7' or 'uuid-utils' PyPI packages, or:
# from uuid_extensions import uuid7
[PostgreSQL]

PostgreSQL 18+ — native uuidv7()-funktion

-- PG 18 ships uuidv7() natively. Use it as a primary key default:
CREATE TABLE events (
    id   uuid PRIMARY KEY DEFAULT uuidv7(),
    body jsonb,
    ts   timestamptz NOT NULL DEFAULT now()
);

-- For older Postgres, install the pg_uuidv7 extension or generate client-side.
-- Migration tip: keep INDEX on (id) only — v7 already sorts chronologically,
-- so a separate (created_at) index is usually redundant.

// ALMINDELIGE FALDGRUBER

> UUIDv7 afslører oprettelsestiden — brug det ikke til uigennemsigtige tokens

De første 48 bit af enhver v7 er et Unix-millisekund-tidsstempel. Enhver, der ser UUID'en, kan afkode, hvornår posten blev oprettet, hastigheden hvormed id'er udstedes, og (med flere prøver) tilnærme serverens ur. Det er fint til interne databaseprimærnøgler og log-id'er, men til URL'er til nulstilling af adgangskode, delelinks, sessions-id'er eller invitationskoder skal du i stedet bruge UUIDv4 eller en CSPRNG-genereret tilfældig streng.

> Urregression bryder monotoni

Hvis systemuret springer baglæns (NTP-trin, VM-migrering, skudsekund), kan naivt genererede v7-UUID'er producere værdier, der sorterer før tidligere udstedte id'er. RFC 9562 §6.2 anbefaler Metode 2 (monoton tilfældig): hold styr på den senest genererede UUID, og når tidsstemplet ikke skrider frem, øg den tilfældige del i stedet. Dette værktøjs Monoton-kontakt gør netop det.

> v7 er ikke en direkte erstatning for v4 i sikkerhedsfølsomme sammenhænge

Tilfældigt udseende id'er (v4) bruges ofte ved et uheld som bearertokens: »hvis du kender UUID'en, kan du læse rækken«. v7 har kun 74 tilfældige bit og et forudsigeligt tidsstempelpræfiks, hvilket stadig er kollisionsbestandigt, men giver langt mindre uforudsigelighed end v4's 122 tilfældige bit. Hvis noget behandles som en capability, så generer et separat kryptografisk token i stedet for at genbruge v7-primærnøglen.

> Strengsammenligning virker kun i små bogstaver med bindestreger

v7's kronologiske sortering afhænger af leksikografisk sammenligning af den kanoniske 36-tegns streng med små bogstaver — eller af byte-for-byte-sammenligning af den underliggende 16-byte-værdi. At blande store og små bogstaver, fjerne bindestreger undervejs eller gemme nogle rækker som {...}-indrammede og andre uden vil alt sammen producere en sorteringsrækkefølge, der ikke længere matcher oprettelsestiden. Vælg én kanonisk form pr. kolonne, og håndhæv den med en CHECK-begrænsning.

> 48-bit-tidsstempel ruller om i år 10889

2^48 millisekunder er cirka 8.925 år efter Unix-epoken — tidsstempelfeltet løber over den 02-08-10889 UTC. Hvis din kode hævder, at det indlejrede tidsstempel ligger i et fornuftigt interval, skal du sætte den øvre grænse til 281.474.976.710.655 ms (det maksimale, et 48-bit fortegnsløst heltal kan rumme) i stedet for at hårdkode et nær-fremtidigt år, der vil være forkert om et århundrede.

>> ofte stillede spørgsmål

Sp: Hvad er UUIDv7?

Sv: UUIDv7 er en 128-bit identifikator defineret i RFC 9562 (maj 2024), der kombinerer et 48-bit Unix-millisekund-tidsstempel med 74 bit tilfældighed og standard version- + variantbit. Resultatet er et globalt unikt id, der også sorterer kronologisk efter oprettelsestid — det bedste fra begge verdener. Det blev designet specifikt til at løse databaseindeksproblemet forårsaget af tilfældige UUIDv4-primærnøgler, hvor hver indsættelse lander på en anden B-træ-side og forårsager massiv skriveforstærkning.

Sp: Hvordan adskiller UUIDv7 sig fra UUIDv4?

Sv: UUIDv4 er fuldt tilfældig (122 tilfældige bit) og har ingen struktur ud over version- + variantfelterne. To v4'er genereret et mikrosekund fra hinanden sorterer til vidt forskellige positioner, hvilket er fremragende for uforudsigelighed, men forfærdeligt for B-træ-indekser. UUIDv7 placerer et 48-bit Unix-millisekund-tidsstempel forrest, så v7'er genereret tæt i tid også sorterer tæt i lageret. Afvejning: v7 afslører oprettelsestiden og har kun 74 tilfældige bit i stedet for 122 — stadig kollisionsbestandigt, men uegnet som hemmeligt token.

Sp: Bør jeg migrere fra UUIDv4 til UUIDv7?

Sv: Til interne databaseprimærnøgler på skrivetunge tabeller — ja, næsten altid. Den indeksfragmentering, som v4 forårsager, kan overstige omkostningerne ved selve forespørgslerne, især på PostgreSQL eller MySQL med InnoDB-klyngede indekser. Til tokens, der eksponeres for brugere, indlejres i URL'er eller behandles som capabilities (»hvis du kender UUID'en, kan du tilgå ressourcen«), behold v4 eller brug et separat tilfældigt token — v7 afslører oprettelsestiden. Et almindeligt mønster er v7-primærnøgler til interne joins plus en separat tilfældig slug til den offentligt vendte URL.

Sp: Er UUIDv7 det samme som ULID, KSUID eller Snowflake?

Sv: Konceptuelt ens — alle fire er tidsordnede id'er — men bit-layouts og kodninger adskiller sig. ULID bruger Crockford base32 og et andet millisekund-layout. KSUID koder et 32-bit tidsstempel + 128-bit payload som 27 base62-tegn. Snowflake er et 64-bit Twitter-specifikt id med worker-id'er. UUIDv7 er den IETF-standardækvivalent, kodet i den kanoniske 8-4-4-4-12-hex-form, så ethvert UUID-bibliotek, databasens UUID-type og JDBC/ODBC-driver allerede forstår det. Hvis du starter på en frisk i 2025+, så foretræk v7 — det er standarden.

Sp: Hvor mange UUIDv7'er kan jeg generere pr. millisekund før kollisioner?

Sv: Inden for et enkelt millisekund giver kun de 74 tilfældige bit (12 i rand_a + 62 i rand_b) unikhed. Ifølge fødselsdagskollisionsgrænsen kan du generere cirka 2^37 ≈ 137 milliarder v7'er i samme ms, før der er 50% kollisionsrisiko — reelt ubegrænset for ethvert realistisk system. På tværs af millisekunder skelner selve tidsstemplet, så den globale kollisionsrisiko over et systems levetid er ubetydelig. Med Monoton-kontakten slået til er kollisioner inden for samme millisekund nul ved konstruktion (den tilfældige del øges).

Sp: Kan jeg udtrække tidsstemplet fra en UUIDv7?

Sv: Ja — tidsstemplet er de første 48 bit, hvilket er de første 12 hex-tegn med bindestregerne fjernet. Sammenkæd de første tre bindestregsgrupper (8 + 4 = 12 hex digits), fortolk som et heksadecimalt heltal, og du har Unix-tidsstemplet i millisekunder. Brug afkoderen ovenfor til at gøre dette interaktivt, eller i kode: parseInt(uuid.replace(/-/g,'').slice(0,12), 16). Resultatet er det millisekund-øjeblik, UUID'en blev genereret, nøjagtigt efter systemuret på det tidspunkt.

Sp: Hvordan ser versionscifferet ud i en UUIDv7?

Sv: Den tredje bindestregsadskilte gruppe begynder altid med cifferet 7. For eksempel: 018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55. Den fjerde gruppe begynder altid med 8, 9, a eller b — det er de fire mulige værdier, når de øverste to bit er 10 (RFC 4122-varianten). Hvis versionscifferet ikke er 7, er UUID'en en anden version (almindeligvis 4 for tilfældig eller 1 for tidsbaseret v1) og sorterer ikke kronologisk.

Sp: Understøtter PostgreSQL / MySQL UUIDv7 nativt?

Sv: PostgreSQL 18 (udgivet september 2025) leverer uuidv7() som en indbygget funktion. Tidligere versioner kræver pg_uuidv7-udvidelsen eller generering på klientsiden. MySQL 8.x har ingen native v7; brug UUID_TO_BIN(uuid, 1)-hjælperen (som bytter tidsstempelbytes om for sorteringsrækkefølge) kun til v1 — til v7 generer på klientsiden. SQL Server, Oracle og SQLite forventer alle generering af v7 på klientsiden. De fleste ORM'er (Hibernate, Entity Framework, Sequelize, Prisma, SQLAlchemy) understøtter nu v7 enten nativt eller via et plugin.

Sp: Er den monotone indstilling i overensstemmelse med RFC 9562?

Sv: Ja. RFC 9562 §6.2 beskriver eksplicit tre metoder til at sikre rækkefølge inden for samme millisekund: (1) tilfældig fyld, (2) monoton tilfældig — øg en tæller, når tidsstemplet ikke skrider frem, (3) sub-millisekund-tidsstempelpræcision. Monoton-afkrydsningsfeltet i dette værktøj implementerer metode 2: når to UUID'er deler samme 48-bit-tidsstempel, sættes den andens tilfældige del til previous_random + 1 i stedet for at blive trukket på ny. Dette garanterer streng rækkefølge for batch-generering, mens det forbliver fuldt specifikationsoverensstemmende.

Sp: Sendes mine data nogen steder hen?

Sv: Nej. Al UUIDv7-generering, -afkodning, -sortering, -kopiering og -download sker udelukkende i din browser som ren JavaScript. Siden foretager aldrig en netværksanmodning, når du klikker på GENERER, AFKOD, KOPIÉR eller HENT — du kan verificere det med din browsers DevTools-netværksfane. Vi logger ikke tidsstempler, brugerdefinerede seeds, genererede UUID'er eller afkodede output. Selve siden er statisk HTML serveret fra et CDN, så intet input når nogensinde vores infrastruktur. Dette gør værktøjet sikkert at bruge til produktionsdatabasе-id'er, interne logs eller andre data, du helst ikke vil sende gennem en tredjepartsserver.

Sp: Kan jeg bruge UUIDv7 i Java / .NET / Rust?

Sv: Ja. Java har com.fasterxml.uuid:java-uuid-generator 5.0+, og JDK 21 har det via bibliotekshjælpere. .NET 9 leverer Guid.CreateVersion7() i BCL. Rust bruger uuid-cratens Uuid::now_v7() bag v7-feature-flaget. De fleste andre økosystemer (Elixir, Ruby, PHP, Swift, Kotlin) har også velholdte pakker — søg efter »uuidv7« eller »uuid v7« i sprogets pakkeregister. Wire-formatet er identisk på tværs af dem alle, så en v7 genereret i Go kan parses og få tidsstemplet udtrukket af JavaScript uden nogen transformation.

Sp: Har Node.js en indbygget UUIDv7-generator?

Sv: Ja — fra og med Node.js v26.1.0 (udgivet 07-05-2026) eksponerer standardbiblioteket crypto.randomUUIDv7([options]). Importér det som import { randomUUIDv7 } from 'node:crypto', og kald det uden argumenter for at få en RFC 9562 v7-UUID-streng. Den eneste understøttede mulighed er disableEntropyCache (boolean, standard false); som standard cacher Node nok tilfældige data på forhånd til at generere de næste ~128 UUID'er, hvilket er samme optimering som brugt af crypto.randomUUID(). Vigtigt forbehold fra den officielle dokumentation: »det indlejrede tidsstempel afhænger af et ikke-monotont ur og er ikke garanteret strengt stigende«. Med andre ord: to UUID'er genereret i samme millisekund, eller enhver UUID oprettet hen over et NTP-trin / VM-urskew baglæns, sorterer måske ikke i oprettelsesrækkefølge. Hvis du har brug for streng monotoni inden for et millisekund, så brug en userland-implementering, der følger RFC 9562 §6.2 Metode 2 (npm-pakken uuidv7 eller dette værktøj med Monoton-kontakten slået til).

Sp: Hvordan gemmer jeg UUIDv7 effektivt i en database?

Sv: Gem den som en 16-byte binær type i stedet for en 36-tegns streng — du sparer 20 byte pr. række, halverer indeksstørrelsen og får en hurtigere sammenligningssti. Brug PostgreSQL's uuid-type, MySQL BINARY(16), SQL Server uniqueidentifier eller SQLite BLOB. Tilføj en CHECK-begrænsning om, at versionsnibblen er lig med 7, hvis du vil håndhæve det. Med v7 klynges rækkerne naturligt efter oprettelsestid, så et dækkende indeks på (uuid_pk) er normalt nok — du behøver ikke et separat (created_at)-indeks til kronologiske forespørgsler.

// OTHER LANGUAGES