> uuidv7 generator <
// Tidsordnede, sorterbare UUID-er (RFC 9562, 2024) — 48-bits Unix-ms-tidsstempel + 74 tilfeldige bit, generert lokalt
// DEKOD / INSPISER EN UUIDV7
Lim inn en hvilken som helst UUID nedenfor for å hente ut det innebygde tidsstempelet, versjonen og varianten. Fungerer med v7 og rapporterer hvis inndataene er en annen UUID-versjon.
Spesifikasjonssamsvarende UUIDv7
Implementerer det tidsordnede UUID-formatet fra RFC 9562 (mai 2024): 48-bits Unix-millisekund-tidsstempel, 4-bits versjon 7, 12-bits rand_a, 2-bits variant, 62-bits rand_b. Verifisert mot spesifikasjonens testvektorer.
Kronologisk sorteringsrekkefølge
Sorter numerisk eller leksikografisk, og du får innsettingsrekkefølgen — perfekt for B-tre-primærnøkler, tidsserieindekser og loggkorrelasjon. Ikke flere tilfeldige v4-sidesplittinger eller fragmenterte indekser.
Monotonisitet innenfor samme millisekund
Når flere UUID-er havner i ett millisekund, økes den tilfeldige delen strengt slik at utdataene forblir sortert innenfor det ms-et. Slå av for ren RFC 9562 Metode 1 (tilfeldig fyll) hvis du foretrekker det.
Inspiser hvilken som helst UUIDv7
Lim inn en v7-UUID, og dekoderen henter ut det innebygde tidsstempelet (ms + ISO 8601), versjonsbitene, variantbitene og feltene rand_a / rand_b. Nyttig for feilsøking, loggarkeologi og revisjonsspor.
// OM UUIDV7
Slik fungerer UUIDv7:
En UUIDv7 er en 128-bits identifikator bygd opp som unix_ts_ms (48) | ver (4) | rand_a (12) | var (2) | rand_b (62). De første 48 bitene er det gjeldende Unix-tidsstempelet i millisekunder, big-endian, noe som gjør UUID-en monotont økende i tid. De neste 4 bitene koder versjonen (binært 0111 = desimal 7), så den tredje bindestrekdelte gruppen begynner alltid med sifferet 7. rand_a er 12 tilfeldige bit brukt til sub-millisekund-oppløsning eller som ekstra entropi. Det 2-bits variantfeltet er fastsatt til 10 (så det første tegnet i den fjerde gruppen er alltid 8, 9, a eller b). De resterende 62 bitene (rand_b) kommer fra crypto.getRandomValues() ved hver generering. Den totale entropien per UUID er 74 tilfeldige bit, noe som er kollisjonsbestandig for enhver realistisk genereringsrate.
Eksempel:
018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55 (ts=2024-05-08T15:00:00.000Z)
Standarder og referanser:
- >RFC 9562 — Universally Unique IDentifiers (UUIDs), mai 2024 (erstatter RFC 4122, definerer v6/v7/v8)
- >RFC 4122 — den opprinnelige UUID-spesifikasjonen fra 2005 (fortsatt autoritativ for v1-v5)
- >Web Crypto API (W3C) —
crypto.getRandomValues()CSPRNG brukt til de 74 tilfeldige bitene - >PostgreSQL
gen_random_uuid()-atferd (v4 som standard, v7 i pgcrypto-utvidelser / forks) - >draft-peabody-dispatch-new-uuid-format — det opprinnelige v6/v7/v8-forslaget som ble til RFC 9562
Hvorfor bruke UUIDv7:
- >Databaseprimærnøkler med innsettingslokalitet — sider holder seg pakket, indekser fragmenteres ikke
- >Erstatter et par av sekvens + UUID: én kolonne, sorterbar OG globalt unik
- >Erstatter v4-primærnøkler i skrivetunge tabeller for å løse problemet med sidesplitting ved tilfeldig innsetting
- >Loggkorrelasjons-ID-er som sorterer etter opprettelsestid uten en egen tidsstempelkolonne
- >Distribuerte systemer der flere skrivere trenger ordnede ID-er uten en koordinator
- >Event sourcing / append-only-logger der kronologisk rekkefølge er den naturlige indeksen
- >S3- / objektlagernøkler der prefikssortering samsvarer med innsettingsrekkefølgen
- >Erstatter Snowflake / KSUID / ULID der et standardformat er å foretrekke
Relaterte verktøy:
- >UUID-generator — genererer v4 (tilfeldig) og v1 (tidsstempel) når du ikke trenger v7s sorteringsrekkefølge
- >GUID-generator — samme identifikator under Microsoft-navngivningen
- >Tidsstempelkonverterer — konverterer de innebygde Unix-ms tilbake til lokal tid / ISO 8601
- >Epoch-konverterer — inspiser 48-bits tidsstempeldelen i en hvilken som helst tidssone
- >Passordgenerator — kryptografisk tilfeldige tokens når sorterbarhet ikke er påkrevd
// EKSEMPELUTDATA
Enkelt UUIDv7 generert nå
count=1, format=standard, timestamp=current
output:
018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55
Massebatch med monotonisitet i samme millisekund
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
Egendefinert historisk tidsstempel — utfylling av en migrering
count=1, timestamp=custom, value=1577836800000 (2020-01-01)
output:
016f5e66-e800-7c9a-b403-2f1d4a7c91ee
Kompakt format for URL-er / filnavn
count=1, format=no-hyphens
output:
018f5c2e90c07a4fb6ee8dfe3c2b0a55
Dekodet UUIDv7 — inspiser de innebygde feltene
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
// IMPLEMENTER DET SELV
De fleste språk har enten en stdlib-hjelper eller en implementering i én fil for UUIDv7 siden RFC 9562 kom i 2024. Nedenfor er de kanoniske oppskriftene du kan slippe inn i kodebasen din — i nettleser-JS, Node.js, Go, Python og PostgreSQL.
UUIDv7 i ren nettleser-/Node-JS — RFC 9562-oppbygning
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 v26.1.0+ — innebygd 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 — 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 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 18+ — native uuidv7()-funksjon
-- 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.
// VANLIGE FALLGRUVER
> UUIDv7 lekker opprettelsestiden — ikke bruk det til ugjennomsiktige tokens
De første 48 bitene av enhver v7 er et Unix-millisekund-tidsstempel. Alle som ser UUID-en, kan dekode når posten ble opprettet, hastigheten ID-er utstedes med, og (med flere prøver) tilnærme serverklokken. Det er greit for interne databaseprimærnøkler og logg-ID-er, men for URL-er for tilbakestilling av passord, delelenker, økt-ID-er eller invitasjonskoder bør du heller bruke UUIDv4 eller en CSPRNG-generert tilfeldig streng.
> Klokkeregresjon bryter monotonisitet
Hvis systemklokken hopper bakover (NTP-trinn, VM-migrering, skuddsekund), kan naivt genererte v7-UUID-er produsere verdier som sorterer før tidligere utstedte ID-er. RFC 9562 §6.2 anbefaler Metode 2 (monoton tilfeldig): hold styr på den sist genererte UUID-en, og når tidsstempelet ikke skrider frem, øk den tilfeldige delen i stedet. Dette verktøyets Monoton-bryter gjør nettopp dette.
> v7 er ikke en direkte erstatning for v4 i sikkerhetssensitive sammenhenger
Tilfeldig utseende ID-er (v4) brukes ofte ved et uhell som bearer-tokens: «hvis du kjenner UUID-en, kan du lese raden». v7 har bare 74 tilfeldige bit og et forutsigbart tidsstempelprefiks, noe som fortsatt er kollisjonsbestandig, men gir langt mindre uforutsigbarhet enn v4s 122 tilfeldige bit. Hvis noe behandles som en capability, generer et eget kryptografisk token i stedet for å gjenbruke v7-primærnøkkelen.
> Strengsammenligning fungerer bare i små bokstaver med bindestreker
v7s kronologiske sortering avhenger av leksikografisk sammenligning av den kanoniske 36-tegns strengen med små bokstaver — eller av byte-for-byte-sammenligning av den underliggende 16-byte-verdien. Å blande store og små bokstaver, fjerne bindestreker underveis eller lagre noen rader som {...}-innrammede og andre uten vil alt sammen produsere en sorteringsrekkefølge som ikke lenger samsvarer med opprettelsestiden. Velg én kanonisk form per kolonne, og håndhev den med en CHECK-begrensning.
> 48-bits tidsstempel ruller rundt i år 10889
2^48 millisekunder er omtrent 8 925 år etter Unix-epoken — tidsstempelfeltet flyter over 02.08.10889 UTC. Hvis koden din hevder at det innebygde tidsstempelet ligger i et fornuftig intervall, sett øvre grense til 281 474 976 710 655 ms (det maksimale et 48-bits fortegnsløst heltall kan romme) i stedet for å hardkode et nær-fremtidig år som vil være feil om et århundre.
>> ofte stilte spørsmål
Sp: Hva er UUIDv7?
Sv: UUIDv7 er en 128-bits identifikator definert i RFC 9562 (mai 2024) som kombinerer et 48-bits Unix-millisekund-tidsstempel med 74 bit tilfeldighet og standard versjons- + variantbit. Resultatet er en globalt unik ID som også sorterer kronologisk etter opprettelsestid — det beste fra begge verdener. Den ble utformet spesifikt for å løse databaseindeksproblemet forårsaket av tilfeldige UUIDv4-primærnøkler, der hver innsetting havner på en annen B-tre-side og forårsaker massiv skriveforsterkning.
Sp: Hvordan skiller UUIDv7 seg fra UUIDv4?
Sv: UUIDv4 er fullstendig tilfeldig (122 tilfeldige bit) og har ingen struktur utover versjons- + variantfeltene. To v4-er generert ett mikrosekund fra hverandre sorterer til vidt forskjellige posisjoner, noe som er flott for uforutsigbarhet, men forferdelig for B-tre-indekser. UUIDv7 plasserer et 48-bits Unix-millisekund-tidsstempel først, så v7-er generert nær i tid sorterer også nær i lagringen. Avveining: v7 lekker opprettelsestiden og har bare 74 tilfeldige bit i stedet for 122 — fortsatt kollisjonsbestandig, men uegnet som hemmelig token.
Sp: Bør jeg migrere fra UUIDv4 til UUIDv7?
Sv: For interne databaseprimærnøkler på skrivetunge tabeller — ja, nesten alltid. Indeksfragmenteringen som v4 forårsaker, kan overstige kostnaden ved selve spørringene, spesielt på PostgreSQL eller MySQL med InnoDB-klyngede indekser. For tokens som eksponeres for brukere, bygges inn i URL-er eller behandles som capabilities («hvis du kjenner UUID-en kan du få tilgang til ressursen»), behold v4 eller bruk et eget tilfeldig token — v7 lekker opprettelsestiden. Et vanlig mønster er v7-primærnøkler for interne joins pluss en egen tilfeldig slug for den offentlige URL-en.
Sp: Er UUIDv7 det samme som ULID, KSUID eller Snowflake?
Sv: Konseptuelt like — alle fire er tidsordnede ID-er — men bit-layoutene og kodingene er forskjellige. ULID bruker Crockford base32 og et annet millisekund-layout. KSUID koder et 32-bits tidsstempel + 128-bits nyttelast som 27 base62-tegn. Snowflake er en 64-bits Twitter-spesifikk ID med worker-ID-er. UUIDv7 er den IETF-standard ekvivalenten, kodet i den kanoniske 8-4-4-4-12-hex-formen, slik at ethvert UUID-bibliotek, databasens UUID-type og JDBC/ODBC-driver allerede forstår den. Hvis du starter på nytt i 2025+, foretrekk v7 — det er standarden.
Sp: Hvor mange UUIDv7-er kan jeg generere per millisekund før kollisjoner?
Sv: Innenfor ett enkelt millisekund gir bare de 74 tilfeldige bitene (12 i rand_a + 62 i rand_b) unikhet. Ifølge fødselsdagskollisjonsgrensen kan du generere omtrent 2^37 ≈ 137 milliarder v7-er i samme ms før det er 50 % kollisjonssjanse — i praksis ubegrenset for ethvert realistisk system. På tvers av millisekunder skiller selve tidsstempelet, så den globale kollisjonsrisikoen over levetiden til et system er ubetydelig. Med Monoton-bryteren på er kollisjoner innenfor samme millisekund null per konstruksjon (den tilfeldige delen økes).
Sp: Kan jeg hente ut tidsstempelet fra en UUIDv7?
Sv: Ja — tidsstempelet er de første 48 bitene, som er de første 12 hex-tegnene med bindestrekene fjernet. Slå sammen de tre første bindestrekgruppene (8 + 4 = 12 hex digits), tolk som et heksadesimalt heltall, og du har Unix-tidsstempelet i millisekunder. Bruk dekoderen ovenfor for å gjøre dette interaktivt, eller i kode: parseInt(uuid.replace(/-/g,'').slice(0,12), 16). Resultatet er millisekund-øyeblikket UUID-en ble generert, nøyaktig etter systemklokken på det tidspunktet.
Sp: Hvordan ser versjonssifferet ut i en UUIDv7?
Sv: Den tredje bindestrekdelte gruppen begynner alltid med sifferet 7. For eksempel: 018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55. Den fjerde gruppen begynner alltid med 8, 9, a eller b — det er de fire mulige verdiene når de øverste to bitene er 10 (RFC 4122-varianten). Hvis versjonssifferet ikke er 7, er UUID-en en annen versjon (vanligvis 4 for tilfeldig eller 1 for tidsbasert v1) og sorterer ikke kronologisk.
Sp: Støtter PostgreSQL / MySQL UUIDv7 nativt?
Sv: PostgreSQL 18 (utgitt september 2025) leverer uuidv7() som en innebygd funksjon. Tidligere versjoner trenger pg_uuidv7-utvidelsen eller generering på klientsiden. MySQL 8.x har ingen native v7; bruk UUID_TO_BIN(uuid, 1)-hjelperen (som bytter om tidsstempelbytes for sorteringsrekkefølge) kun for v1 — for v7 generer på klientsiden. SQL Server, Oracle og SQLite forventer alle generering av v7 på klientsiden. De fleste ORM-er (Hibernate, Entity Framework, Sequelize, Prisma, SQLAlchemy) støtter nå v7 enten nativt eller via en plugin.
Sp: Er det monotone alternativet i samsvar med RFC 9562?
Sv: Ja. RFC 9562 §6.2 beskriver eksplisitt tre metoder for å sikre rekkefølge innenfor samme millisekund: (1) tilfeldig fyll, (2) monoton tilfeldig — øk en teller når tidsstempelet ikke skrider frem, (3) sub-millisekund-tidsstempelpresisjon. Monoton-avkrysningsboksen i dette verktøyet implementerer metode 2: når to UUID-er deler samme 48-bits tidsstempel, settes den andres tilfeldige del til previous_random + 1 i stedet for å trekkes på nytt. Dette garanterer streng rekkefølge for batch-generering samtidig som det forblir fullt spesifikasjonssamsvarende.
Sp: Sendes dataene mine noe sted?
Sv: Nei. All UUIDv7-generering, -dekoding, -sortering, -kopiering og -nedlasting skjer fullstendig i nettleseren din som ren JavaScript. Siden gjør aldri en nettverksforespørsel når du klikker GENERER, DEKOD, KOPIER eller LAST NED — du kan verifisere det med nettverksfanen i nettleserens DevTools. Vi logger ikke tidsstempler, egendefinerte seeds, genererte UUID-er eller dekodede utdata. Selve siden er statisk HTML servert fra et CDN, så ingen inndata når noen gang infrastrukturen vår. Dette gjør verktøyet trygt å bruke for produksjonsdatabasе-ID-er, interne logger eller andre data du helst ikke vil sende gjennom en tredjepartsserver.
Sp: Kan jeg bruke UUIDv7 i Java / .NET / Rust?
Sv: Ja. Java har com.fasterxml.uuid:java-uuid-generator 5.0+, og JDK 21 har det via bibliotekshjelpere. .NET 9 leverer Guid.CreateVersion7() i BCL. Rust bruker uuid-cratens Uuid::now_v7() bak v7-feature-flagget. De fleste andre økosystemer (Elixir, Ruby, PHP, Swift, Kotlin) har også godt vedlikeholdte pakker — søk etter «uuidv7» eller «uuid v7» i språkets pakkeregister. Wire-formatet er identisk på tvers av alle, så en v7 generert i Go kan parses og få tidsstempelet hentet ut av JavaScript uten noen transformasjon.
Sp: Har Node.js en innebygd UUIDv7-generator?
Sv: Ja — fra og med Node.js v26.1.0 (utgitt 07.05.2026) eksponerer standardbiblioteket crypto.randomUUIDv7([options]). Importer det som import { randomUUIDv7 } from 'node:crypto' og kall det uten argumenter for å få en RFC 9562 v7-UUID-streng. Det eneste støttede alternativet er disableEntropyCache (boolsk, standard false); som standard cacher Node nok tilfeldige data på forhånd til å generere de neste ~128 UUID-ene, som er samme optimalisering som brukes av crypto.randomUUID(). Viktig forbehold fra den offisielle dokumentasjonen: «det innebygde tidsstempelet avhenger av en ikke-monoton klokke og er ikke garantert strengt økende». Med andre ord: to UUID-er generert i samme millisekund, eller en hvilken som helst UUID opprettet over et NTP-trinn / VM-klokkeskjevhet bakover, sorterer kanskje ikke i opprettelsesrekkefølge. Hvis du trenger streng monotonisitet innenfor et millisekund, bruk en userland-implementering som følger RFC 9562 §6.2 Metode 2 (npm-pakken uuidv7, eller dette verktøyet med Monoton-bryteren på).
Sp: Hvordan lagrer jeg UUIDv7 effektivt i en database?
Sv: Lagre den som en 16-byte binær type i stedet for en 36-tegns streng — du sparer 20 byte per rad, halverer indeksstørrelsen og får en raskere sammenligningssti. Bruk PostgreSQLs uuid-type, MySQL BINARY(16), SQL Server uniqueidentifier eller SQLite BLOB. Legg til en CHECK-begrensning om at versjonsnibblen er lik 7 hvis du vil håndheve det. Med v7 klynges radene naturlig etter opprettelsestid, så en dekkende indeks på (uuid_pk) er vanligvis nok — du trenger ikke en egen (created_at)-indeks for kronologiske spørringer.