Skip to content

Comparison

UUID v4 vs v7: escolha v7 para chaves de banco de dados

v4 para tokens opacos. v7 para todo o resto, especialmente chaves de banco de dados.

By Published

Resumo. UUID v4 tem 122 bits de aleatório puro e não é ordenável, o que destrói o desempenho do índice B-tree quando usado como chave de banco de dados. UUID v7 (RFC 9562, 2024) prepende um timestamp Unix de 48 bits em milissegundos para que os IDs se ordenem por tempo de criação. Use v7 para chaves de banco de dados e IDs de eventos; mantenha v4 para tokens de sessão opacos.

UUIDs são identificadores de 128 bits projetados para ser globalmente únicos entre sistemas sem coordenação. A especificação original (RFC 4122, 2005) definiu cinco versões; v4 (puro aleatório) era a única que a maioria dos desenvolvedores usava. RFC 9562 (2024) adicionou v7, e v7 deve ser o novo padrão para quase todo caso de uso onde v4 era anteriormente escolhido.

As principais diferenças

Propriedadev4v7
EspecificadoRFC 4122 (2005)RFC 9562 (2024)
Bits aleatórios12274
Timestamp embutidoNãoSim (48 bits ms desde epoch)
Ordenável por tempo de criaçãoNão (puro aleatório)Sim (lexicográfico = cronológico)
Probabilidade de colisão~1 em 10³⁶ para qualquer parEfetivamente zero (timestamp + aleatório combinados)
Amigabilidade ao índice de banco de dadosRuim (inserção aleatória agita B-trees)Excelente (sequencial, amigável ao append)
Suporte no navegadorcrypto.randomUUID() desde 2021Geração manual (sem API nativa ainda)

Por que v4 prejudica bancos de dados

Chaves primárias de banco de dados geralmente ficam em um índice B-tree. B-trees funcionam melhor quando as inserções chegam em ordem classificada: novas chaves se appendam à folha mais à direita, sem necessidade de rebalanceamento, a página do índice permanece quente no cache.

Chaves aleatórias (v4) destroem tudo isso. Cada inserção cai em uma página aleatória, potencialmente causando uma divisão de página, certamente causando faltas de cache, e produzindo espaço livre espalhado pelo índice que nunca é compactado. Para cargas de trabalho pesadas em escrita, isso se manifesta como:

  • 10-100× mais I/O do que chaves sequenciais na mesma taxa de escrita
  • Arquivos de índice inflados (frequentemente 2-3× do tamanho que teriam com chaves ordenadas)
  • Lentidão nas consultas à medida que a taxa de acerto de cache se degrada

Os benchmarks de Postgres vs MySQL comparando UUID v4 com chaves primárias bigint consistentemente mostram diferença de throughput de escrita de 2-5× em cargas de trabalho representativas. A solução não é abandonar UUIDs — é usar o tipo de UUID que se ordena.

Como v7 parece

Um UUID v7:

01950d29-4f6f-7234-bf01-a8b3c0d9e102
└─────timestamp_ms──────┘     └──aleatório──┘

Primeiros 48 bits: timestamp Unix em milissegundos (bom até ~10889 d.C.). Próximos 4 bits: versão (sempre 7). Próximos 12 bits: aleatório. Depois 2 bits de marcador de variante + 62 bits de aleatório. Total aleatório: 74 bits — confortavelmente resistente a colisões.

Dois UUIDs v7 criados no mesmo milissegundo competem nos 74 bits de aleatório; a probabilidade de colisão dentro desse milissegundo é aproximadamente 10⁻²² para um sistema de bilhões de IDs. Entre milissegundos, o timestamp torna as colisões estruturalmente impossíveis.

Quando v4 ainda é a escolha certa

  • Tokens de sessão opacos onde você não quer a ordem de criação vazada. v7 vaza timestamps de criação com resolução de ~milissegundo no prefixo, o que está bem para chaves de banco de dados, mas é ruim para tokens sensíveis à privacidade.
  • Chaves de API, tokens de acesso, tokens de redefinição de senha: opacidade importa mais que ordenabilidade.
  • Identificadores de anonimização: onde observar o timestamp ajudaria um atacante a correlacionar.

Quando v7 é claramente melhor

  • Chaves primárias de banco de dados.
  • IDs de sistemas distribuídos (IDs de evento, IDs de pedido, IDs de rastreamento).
  • Qualquer lugar onde você se beneficiaria de poder ORDER BY id e obter ordenação cronológica gratuitamente.
  • Qualquer lugar onde consultas de intervalo no tempo de criação de outra forma precisariam de um índice separado em created_at.

O caminho de migração

Novas tabelas: use v7 desde o início. Tabelas antigas: geralmente não vale a migração, mas se você está atingindo limites de throughput de escrita em uma tabela com chave UUID, mudar para v7 é uma mudança estrutural valiosa.

Gere qualquer um via nosso gerador de UUID, que suporta ambas as versões.

Dados numéricos

  • Comprimento da string: ambos têm 36 caracteres quando hifenizados (32 hex + 4 hífens), 32 chars sem hífens, 22 chars em base64url, 16 bytes brutos.
  • Entropia: v4 tem 122 bits aleatórios (6 bits consumidos por marcadores de versão + variante); v7 tem 74 bits aleatórios após o timestamp de 48 bits.
  • Matemática de colisão v4: 50% de probabilidade de colisão após gerar ~2⁶¹ ≈ 2,3 × 10¹⁸ UUIDs — gere um bilhão por segundo e você esperaria ~85 anos.
  • Intervalo de timestamp v7: campo Unix-milissegundo de 48 bits cobre do ano 1970 ao ano 10889.
  • Benchmark B-tree do Postgres (Percona, 2023): ~7.000 inserções/s com v4 vs ~28.000 inserções/s com v7/ULID no mesmo hardware e schema — uma diferença de 4× que aumenta à medida que o índice cresce além da RAM.
  • Inchaço do índice: uma tabela com 100 M de linhas com chave v4 comumente termina 2-3× maior em disco do que os mesmos dados com chave v7 ou bigint sequencial, devido ao espaço livre deixado após divisões de página.
  • Velocidade de geração: crypto.randomUUID() (v4) roda a ~3 M ops/s no Node 20; implementações v7 (uuid v9, ulid) marcam ~2,5 M ops/s.

Matriz de decisão

Caso de usoEscolha
Chave primária Postgres / MySQLv7 (ou ULID)
ID de evento distribuído, ID de rastreamento, ID de pedidov7
Token de sessão, token CSRFv4 (opacidade importa)
Token de redefinição de senha / magic-linkv4 + TTL curto
Prefixo de chave de APIv4
Chave de objeto S3 (listagem ordenável)v7
Chave de idempotência na entrega de webhookv7 (ordem cronológica amigável ao debug)
Slug públicoNenhum — use NanoID ou hash curto

Fontes

  • RFC 9562 — Universally Unique IDentifiers (UUIDs), maio de 2024 — rfc-editor.org/rfc/rfc9562 (define v6, v7, v8; substitui RFC 4122).
  • Percona Blog — UUIDs in Databases: A Deep Dive, benchmarks v4 vs chaves sequenciais — percona.com.

Frequently asked questions

UUID v7 é retrocompatível com v4?
Sim — ambos são identificadores de 128 bits no mesmo formato hex 8-4-4-4-12, ambos cabem em qualquer coluna ou API que aceite um UUID v4, e ambos codificam sua versão no mesmo nibble. A migração é puramente sobre como você gera novos IDs; IDs v4 existentes no banco de dados continuam funcionando sem alteração.
v7 vaza o timestamp de criação?
Sim — os primeiros 48 bits são o timestamp Unix em milissegundos, legível por qualquer pessoa que veja o UUID. Para a maioria das chaves de banco de dados isso está bem ou é até útil, mas para tokens de sessão opacos ou códigos de redefinição de senha onde você não quer a ordem de criação exposta, use v4.
Por que v4 prejudica o desempenho do banco de dados?
Porque chaves aleatórias caem em páginas aleatórias de um índice B-tree a cada inserção, causando divisões de página e destruindo a localidade do cache. Chaves sequenciais (como o prefixo de timestamp do v7) se appendam à folha mais à direita e permanecem amigáveis ao cache. Benchmarks do Postgres e MySQL tipicamente mostram diferença de throughput de escrita de 2-5×.
Posso gerar UUIDs v7 no navegador?
Não nativamente ainda — crypto.randomUUID() retorna v4. Você precisa de uma pequena biblioteca (uuid v9+, polyfills baseados em ulid) ou 10 linhas de código combinando Date.now() com crypto.getRandomValues(). Suporte nativo a v7 está no roteiro do WHATWG.

Related

Published May 15, 2026