uuidv7 | rfc 9562 | ordinabile per tempo

> uuidv7 generator <

// UUID ordinati per tempo (RFC 9562, 2024) — timestamp Unix a 48 bit in ms + 74 bit casuali, generati localmente

// DECODIFICA / ISPEZIONA UN UUIDV7

Incolla qui sotto un UUID qualsiasi per estrarre il timestamp incorporato, la versione e la variante. Funziona con v7 e segnala se l'input è una versione UUID diversa.

Timestamp (ms): // i campi decodificati appaiono qui
ISO 8601 UTC: // i campi decodificati appaiono qui
Età: // i campi decodificati appaiono qui
Versione: // i campi decodificati appaiono qui
Variante: // i campi decodificati appaiono qui
rand_a (12 bit): // i campi decodificati appaiono qui
rand_b (62 bit): // i campi decodificati appaiono qui
[RFC 9562]

UUIDv7 conforme alle specifiche

Implementa il formato UUID ordinato per tempo di RFC 9562 (maggio 2024): timestamp Unix a 48 bit in millisecondi, versione 7 a 4 bit, rand_a a 12 bit, variante a 2 bit, rand_b a 62 bit. Verificato rispetto ai vettori di test delle specifiche.

[SORTABLE]

Ordine di ordinamento cronologico

Ordina numericamente o lessicograficamente e ottieni l'ordine di inserimento — perfetto per chiavi primarie B-tree, indici di serie temporali e correlazione dei log. Niente più divisioni di pagina casuali di v4 o indici frammentati.

[MONOTONIC]

Monotonicità nello stesso millisecondo

Quando più UUID cadono in un millisecondo, la parte casuale viene incrementata rigorosamente in modo che l'output rimanga ordinato all'interno di quel ms. Disattivalo per il semplice Metodo 1 di RFC 9562 (riempimento casuale) se preferisci.

[DECODER]

Ispeziona qualsiasi UUIDv7

Incolla un UUID v7 e il decodificatore estrae il timestamp incorporato (ms + ISO 8601), i bit di versione, i bit di variante e i campi rand_a / rand_b. Utile per il debugging, l'archeologia dei log e gli audit trail.

// INFORMAZIONI SU UUIDV7

Come funziona UUIDv7:

Un UUIDv7 è un identificatore a 128 bit strutturato come unix_ts_ms (48) | ver (4) | rand_a (12) | var (2) | rand_b (62). I primi 48 bit sono il timestamp Unix attuale in millisecondi, big-endian, il che rende l'UUID monotonicamente crescente nel tempo. I successivi 4 bit codificano la versione (binario 0111 = decimale 7), quindi il terzo gruppo delimitato da trattini inizia sempre con la cifra 7. rand_a è composto da 12 bit casuali usati per la risoluzione sub-millisecondo o come entropia aggiuntiva. Il campo variante a 2 bit è fissato a 10 (quindi il primo carattere del quarto gruppo è sempre 8, 9, a o b). I restanti 62 bit (rand_b) provengono da crypto.getRandomValues() a ogni generazione. L'entropia totale per UUID è di 74 bit casuali, resistente alle collisioni per qualsiasi frequenza di generazione realistica.

Esempio:

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

Standard e riferimenti:

  • >RFC 9562 — Universally Unique IDentifiers (UUIDs), maggio 2024 (rende obsoleto RFC 4122, definisce v6/v7/v8)
  • >RFC 4122 — la specifica UUID originale del 2005 (ancora autorevole per v1-v5)
  • >Web Crypto API (W3C) — crypto.getRandomValues() CSPRNG usato per i 74 bit casuali
  • >Comportamento di gen_random_uuid() in PostgreSQL (v4 per impostazione predefinita, v7 nelle estensioni pgcrypto / fork)
  • >draft-peabody-dispatch-new-uuid-format — la proposta originale v6/v7/v8 che è diventata RFC 9562

Perché usare UUIDv7:

  • >Chiavi primarie di database con località di inserimento — le pagine restano compatte, gli indici non si frammentano
  • >Sostituisce una coppia sequenza + UUID: una colonna, ordinabile E globalmente unica
  • >Sostituisce le chiavi primarie v4 nelle tabelle con scritture intense per risolvere il problema della divisione di pagina da inserimenti casuali
  • >ID di correlazione dei log che si ordinano per ora di creazione senza una colonna timestamp separata
  • >Sistemi distribuiti in cui più scrittori necessitano di ID ordinati senza un coordinatore
  • >Event sourcing / log append-only in cui l'ordine cronologico è l'indice naturale
  • >Chiavi S3 / di object storage in cui l'ordinamento per prefisso corrisponde all'ordine di inserimento
  • >Sostituisce Snowflake / KSUID / ULID dove è preferibile un formato standard

Strumenti correlati:

// ESEMPI DI OUTPUT

Singolo UUIDv7 generato ora

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

output:

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

Batch in blocco con monotonicità nello stesso millisecondo

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

Timestamp storico personalizzato — backfill di una migrazione

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

output:

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

Formato compatto per URL / nomi file

config: count=1, format=no-hyphens

output:

018f5c2e90c07a4fb6ee8dfe3c2b0a55

UUIDv7 decodificato — ispeziona i campi incorporati

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

// IMPLEMENTALO TU STESSO

La maggior parte dei linguaggi ha un helper della libreria standard o un'implementazione in un singolo file per UUIDv7 da quando RFC 9562 è arrivato nel 2024. Di seguito le ricette canoniche che puoi inserire nel tuo codice — in JS del browser, Node.js, Go, Python e PostgreSQL.

[JavaScript]

UUIDv7 in puro JS browser/Node — struttura RFC 9562

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+ — crypto.randomUUIDv7() integrato

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+ include UUIDv7 nativamente

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+ — uuid.uuid7() della libreria standard

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+ — funzione nativa uuidv7()

-- 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.

// INSIDIE COMUNI

> UUIDv7 rivela l'ora di creazione — non usarlo per token opachi

I primi 48 bit di ogni v7 sono un timestamp Unix in millisecondi. Chiunque veda l'UUID può decodificare quando è stato creato il record, la velocità con cui vengono emessi gli ID e (con più campioni) approssimare l'orologio del server. Va bene per chiavi primarie di database interne e ID di log, ma per URL di reset password, link di condivisione, ID di sessione o codici invito usa invece UUIDv4 o una stringa casuale generata da CSPRNG.

> La regressione dell'orologio rompe la monotonicità

Se l'orologio di sistema salta indietro (step NTP, migrazione VM, secondo intercalare), gli UUID v7 generati in modo ingenuo possono produrre valori che si ordinano prima degli ID emessi in precedenza. RFC 9562 §6.2 consiglia il Metodo 2 (casuale monotono): tenere traccia dell'ultimo UUID generato e, quando il timestamp non avanza, incrementare invece la parte casuale. L'interruttore Monotono di questo strumento fa esattamente questo.

> v7 non è un sostituto immediato di v4 in contesti sensibili alla sicurezza

Gli ID dall'aspetto casuale (v4) vengono spesso usati per errore come bearer token: «se conosci l'UUID, puoi leggere la riga». v7 ha solo 74 bit casuali e un prefisso timestamp prevedibile, che è ancora resistente alle collisioni ma offre molta meno imprevedibilità dei 122 bit casuali di v4. Se qualcosa è trattato come una capability, genera un token crittografico separato invece di riutilizzare la chiave primaria v7.

> Il confronto tra stringhe funziona solo in forma minuscola e con trattini

L'ordinamento cronologico di v7 si basa sul confronto lessicografico della stringa canonica di 36 caratteri minuscoli — o sul confronto byte per byte del valore sottostante a 16 byte. Mescolare maiuscole e minuscole, rimuovere i trattini a metà strada o memorizzare alcune righe tra {...} e altre senza produrrà in ogni caso un ordinamento che non corrisponde più all'ora di creazione. Scegli una forma canonica per colonna e applicala con un vincolo CHECK.

> Il timestamp a 48 bit si azzera nell'anno 10889

2^48 millisecondi sono circa 8.925 anni dopo l'epoca Unix — il campo timestamp va in overflow il 02-08-10889 UTC. Se il tuo codice afferma che il timestamp incorporato è in un intervallo sensato, imposta il limite superiore a 281.474.976.710.655 ms (il massimo che un intero senza segno a 48 bit può contenere) invece di codificare un anno prossimo nel futuro che tra un secolo sarà sbagliato.

>> domande frequenti

D: Cos'è UUIDv7?

R: UUIDv7 è un identificatore a 128 bit definito in RFC 9562 (maggio 2024) che combina un timestamp Unix a 48 bit in millisecondi con 74 bit di casualità e i bit standard di versione + variante. Il risultato è un ID globalmente unico che si ordina anche cronologicamente per ora di creazione — il meglio di entrambi i mondi. È stato progettato specificamente per risolvere il problema degli indici di database causato dalle chiavi primarie UUIDv4 casuali, in cui ogni inserimento finisce in una pagina B-tree diversa e causa una massiccia amplificazione delle scritture.

D: In cosa differisce UUIDv7 da UUIDv4?

R: UUIDv4 è completamente casuale (122 bit casuali) e non ha struttura oltre ai campi versione + variante. Due v4 generati a un microsecondo di distanza si ordinano in posizioni completamente diverse, ottimo per l'imprevedibilità ma pessimo per gli indici B-tree. UUIDv7 mette un timestamp Unix a 48 bit in millisecondi all'inizio, quindi i v7 generati vicini nel tempo si ordinano vicini anche in memoria. Compromesso: v7 rivela l'ora di creazione e ha solo 74 bit casuali invece di 122 — ancora resistente alle collisioni, ma inadatto come token segreto.

D: Dovrei migrare da UUIDv4 a UUIDv7?

R: Per le chiavi primarie di database interne su tabelle con scritture intense — sì, quasi sempre. La frammentazione dell'indice causata da v4 può superare il costo delle query stesse, specialmente su PostgreSQL o MySQL con indici clustered InnoDB. Per i token esposti agli utenti, incorporati negli URL o trattati come capability («se conosci l'UUID puoi accedere alla risorsa»), mantieni v4 o usa un token casuale separato — v7 rivela l'ora di creazione. Uno schema comune sono le chiavi primarie v7 per i join interni più uno slug casuale separato per l'URL pubblico.

D: UUIDv7 è uguale a ULID, KSUID o Snowflake?

R: Concettualmente simili — tutti e quattro sono ID ordinati per tempo — ma i layout dei bit e le codifiche differiscono. ULID usa Crockford base32 e un layout dei millisecondi diverso. KSUID codifica un timestamp a 32 bit + payload a 128 bit come 27 caratteri base62. Snowflake è un ID a 64 bit specifico di Twitter con worker ID. UUIDv7 è l'equivalente standard IETF, codificato nella forma esadecimale canonica 8-4-4-4-12, così che ogni libreria UUID, tipo UUID di database e driver JDBC/ODBC lo comprende già. Se parti da zero nel 2025+, preferisci v7 — è lo standard.

D: Quanti UUIDv7 posso generare per millisecondo prima delle collisioni?

R: All'interno di un singolo millisecondo, solo i 74 bit casuali (12 in rand_a + 62 in rand_b) garantiscono l'unicità. Per il limite della collisione del compleanno, puoi generare circa 2^37 ≈ 137 miliardi di v7 nello stesso ms prima di una probabilità di collisione del 50% — di fatto illimitato per qualsiasi sistema realistico. Tra millisecondi diversi è il timestamp stesso a disambiguare, quindi il rischio di collisione globale per tutta la vita di un sistema è trascurabile. Con l'interruttore Monotono attivo, le collisioni intra-millisecondo sono nulle per costruzione (la parte casuale viene incrementata).

D: Posso estrarre il timestamp da un UUIDv7?

R: Sì — il timestamp è costituito dai primi 48 bit, ovvero i primi 12 caratteri esadecimali con i trattini rimossi. Concatena i primi tre gruppi separati da trattini (8 + 4 = 12 hex digits), interpretali come intero esadecimale e otterrai il timestamp Unix in millisecondi. Usa il decodificatore qui sopra per farlo in modo interattivo, oppure nel codice: parseInt(uuid.replace(/-/g,'').slice(0,12), 16). Il risultato è l'istante in millisecondi in cui l'UUID è stato generato, preciso quanto l'orologio di sistema in quel momento.

D: Come appare la cifra di versione in un UUIDv7?

R: Il terzo gruppo delimitato da trattini inizia sempre con la cifra 7. Per esempio: 018f5c2e-90c0-7a4f-b6ee-8dfe3c2b0a55. Il quarto gruppo inizia sempre con 8, 9, a o b — questi sono i quattro valori possibili con i due bit alti a 10 (la variante RFC 4122). Se la cifra di versione non è 7, l'UUID è di un'altra versione (comunemente 4 per casuale o 1 per v1 basato sul tempo) e non si ordina cronologicamente.

D: PostgreSQL / MySQL supportano UUIDv7 nativamente?

R: PostgreSQL 18 (rilasciato a settembre 2025) include uuidv7() come funzione integrata. Le versioni precedenti necessitano dell'estensione pg_uuidv7 o della generazione lato client. MySQL 8.x non ha v7 nativo; usa l'helper UUID_TO_BIN(uuid, 1) (che scambia i byte del timestamp per l'ordinamento) solo per v1 — per v7 genera lato client. SQL Server, Oracle e SQLite si aspettano tutti la generazione di v7 lato client. La maggior parte degli ORM (Hibernate, Entity Framework, Sequelize, Prisma, SQLAlchemy) ora supporta v7 nativamente o tramite plugin.

D: L'opzione monotona è conforme a RFC 9562?

R: Sì. RFC 9562 §6.2 descrive esplicitamente tre metodi per garantire l'ordinamento intra-millisecondo: (1) riempimento casuale, (2) casuale monotono — incrementare un contatore quando il timestamp non avanza, (3) precisione del timestamp sub-millisecondo. La casella di controllo Monotono in questo strumento implementa il metodo 2: quando due UUID condividono lo stesso timestamp a 48 bit, la parte casuale del secondo viene impostata a previous_random + 1 invece di essere estratta da capo. Questo garantisce un ordinamento rigoroso per la generazione in blocco rimanendo pienamente conforme alle specifiche.

D: I miei dati vengono inviati da qualche parte?

R: No. Tutta la generazione, la decodifica, l'ordinamento, la copia e il download di UUIDv7 avvengono interamente nel tuo browser come puro JavaScript. La pagina non effettua mai una richiesta di rete quando fai clic su GENERA, DECODIFICA, COPIA o SCARICA — puoi verificarlo con la scheda Rete degli strumenti per sviluppatori del tuo browser. Non registriamo timestamp, seed personalizzati, UUID generati o output decodificati. La pagina stessa è HTML statico servito da una CDN, quindi nessun input raggiunge mai la nostra infrastruttura. Questo rende lo strumento sicuro per ID di database di produzione, log interni o qualsiasi altro dato che preferiresti non far passare attraverso un server di terze parti.

D: Posso usare UUIDv7 in Java / .NET / Rust?

R: Sì. Java ha com.fasterxml.uuid:java-uuid-generator 5.0+ e JDK 21 lo ha tramite helper di libreria. .NET 9 include Guid.CreateVersion7() nella BCL. Rust usa Uuid::now_v7() del crate uuid dietro il feature flag v7. La maggior parte degli altri ecosistemi (Elixir, Ruby, PHP, Swift, Kotlin) ha anch'essa pacchetti ben mantenuti — cerca «uuidv7» o «uuid v7» nel registro dei pacchetti del linguaggio. Il formato wire è identico per tutti, quindi un v7 generato in Go può essere interpretato e con timestamp estratto da JavaScript senza alcuna trasformazione.

D: Node.js ha un generatore UUIDv7 integrato?

R: Sì — a partire da Node.js v26.1.0 (rilasciato il 07-05-2026) la libreria standard espone crypto.randomUUIDv7([options]). Importalo come import { randomUUIDv7 } from 'node:crypto' e chiamalo senza argomenti per ottenere una stringa UUID v7 RFC 9562. L'unica opzione supportata è disableEntropyCache (booleano, predefinito false); per impostazione predefinita Node memorizza nella cache abbastanza dati casuali in anticipo da generare i prossimi ~128 UUID, la stessa ottimizzazione usata da crypto.randomUUID(). Avvertenza importante dalla documentazione ufficiale: «il timestamp incorporato si basa su un orologio non monotono e non è garantito che sia strettamente crescente». In altre parole, due UUID generati nello stesso millisecondo, o qualsiasi UUID creato a cavallo di uno step NTP / scostamento all'indietro dell'orologio VM, potrebbero non ordinarsi per ora di creazione. Se hai bisogno di una monotonicità rigorosa entro un millisecondo, usa un'implementazione userland che segue RFC 9562 §6.2 Metodo 2 (il pacchetto npm uuidv7, o questo strumento con l'interruttore Monotono attivo).

D: Come memorizzo UUIDv7 in modo efficiente in un database?

R: Memorizzalo come tipo binario a 16 byte anziché come stringa di 36 caratteri — risparmi 20 byte per riga, dimezzi la dimensione dell'indice e ottieni un percorso di confronto più veloce. Usa il tipo uuid di PostgreSQL, MySQL BINARY(16), SQL Server uniqueidentifier o SQLite BLOB. Aggiungi un vincolo CHECK che il nibble di versione sia uguale a 7 se vuoi applicarlo. Con v7 le righe si raggruppano naturalmente per ora di creazione, quindi un indice di copertura su (uuid_pk) è di solito sufficiente — non serve un indice (created_at) separato per le query cronologiche.

// OTHER LANGUAGES