Use v7 quando o UUID vai ser a chave primária de um banco de dados. Use v4 quando o identificador vai ser visto por pessoas que não têm por que saber quando a linha foi criada. Essa é a decisão inteira, e ela se resume a uma diferença estrutural: um UUID v7 começa com um timestamp Unix de 48 bits em milissegundos, então valores gerados depois ficam ordenados atrás dos gerados antes. Um UUID v4 são 122 bits aleatórios e mais nada, então ele não fica em nenhuma ordem em particular e não revela absolutamente nada.
O que muda de fato nos bits?
Os dois têm 128 bits, escritos como 32 dígitos hexadecimais no padrão 8-4-4-4-12 que dá 36 caracteres com os hífens. Os dois gastam 4 bits num nibble de versão e 2 num marcador de variante. O resto é onde eles se separam.
- v4 — os 122 bits restantes são aleatórios. Sem hora, sem identidade de máquina, sem estrutura de tipo nenhum. Dois UUIDs v4 feitos com um ano de diferença são indistinguíveis de dois feitos no mesmo segundo.
- v7 — os primeiros 48 bits são a hora Unix em milissegundos, big-endian. Os marcadores de versão e variante ficam atrás dele, e os 74 bits que sobram são aleatórios. Ordene um monte deles como texto e eles voltam na ordem de criação.
| v4 | v7 | |
|---|---|---|
| Estrutura | 122 bits aleatórios | relógio de milissegundos de 48 bits, depois 74 bits aleatórios |
| Fica em ordem de criação | Não | Sim, entre milissegundos diferentes |
| Revela quando foi criado | Não | Sim, no milissegundo |
| Adivinhável | Não | Não |
| Use quando | O valor é público e a hora não | O valor é uma chave primária |
A versão fica no décimo terceiro dígito hexadecimal, o que vem logo depois do segundo hífen: um 4 ou um 7. Se você tem um identificador na sua frente e não faz ideia de qual dos dois é, o inspetor do gerador de UUID lê esse nibble e, no caso de um v7, decodifica os primeiros bytes de volta para uma data e uma hora.
Esse valor inicial é uma contagem comum de milissegundos desde 1º de janeiro de 1970 UTC — o mesmo número que um timestamp Unix guarda, armazenado como hexadecimal big-endian em vez de escrito em decimal. Não tem nada de engenhoso ali. É a leitura de um relógio colada na frente de um número aleatório.
Por que o v7 indexa melhor?
Bancos de dados guardam as chaves primárias em uma árvore B ordenada. Uma chave v4 cai num ponto aleatório dessa árvore. Numa tabela pequena isso não custa nada, porque o índice inteiro está na memória. Numa grande, o banco busca no disco a página de destino, e quando essa página está cheia ele a divide em duas, deixando as duas pela metade. Alguns milhões de inserções depois, o índice está maior do que precisa ser, espalhado e meio vazio, e sendo relido do armazenamento o tempo todo.
Uma chave v7 entra no fim. Todo valor é maior que os gerados em milissegundos anteriores, então as inserções caem na página mais à direita da árvore — a que já está na memória porque você acabou de escrever nela. As páginas enchem por completo em vez de se dividir no meio, e o conjunto de páginas tocadas continua pequeno por maior que a tabela fique.
A ressalva honesta: isso só começa a importar quando o índice deixa de caber na RAM. Numa tabela pequena você não vai medir nada, e quem cita um ganho dramático sem dizer a contagem de linhas e o hardware está citando um benchmark construído para produzir esse ganho. O motivo para usar v7 como padrão mesmo assim é que a tabela que você vai ter daqui a três anos é a que vai sentir a diferença, e trocar o tipo de uma chave primária depois é genuinamente doloroso.
O que um UUID v7 revela?
O timestamp não é criptografado nem ofuscado. Qualquer um que tenha um UUID v7 consegue ler o milissegundo em que ele foi feito, e qualquer um que tenha dois consegue ler o intervalo entre eles. Se o identificador aparece numa URL, numa fatura ou numa resposta de API, você publicou isso.
Às vezes é inofensivo. Às vezes é um concorrente contando seus IDs de pedido durante uma semana para estimar seu ritmo de vendas, ou um usuário descobrindo que uma conta marcada como "membro desde 2019" foi criada na terça passada. Decida em qual dos dois casos você está antes de colocar v7 num campo público.
O que o v7 não faz é tornar os identificadores adivinháveis. Os 74 bits aleatórios que sobram são muitos demais para enumerar, então ninguém vai percorrer seu banco de dados incrementando um UUID. O vazamento é o timestamp, não a sequência.
Nenhuma das duas versões é um segredo. UUIDs são tratados como identificadores em tudo que vem depois, então eles acabam em logs de servidor, em eventos de analytics, em cabeçalhos Referer e em prints colados no chat. Se você precisa de um token de redefinição de senha ou de um link de compartilhamento impossível de adivinhar, use um gerador de senhas feito para segredos e guarde um hash dele, em vez de reaproveitar um ID que metade da sua stack está escrevendo em disco em texto puro.
Onde o v7 não ajuda?
SQL Server, se você usar o tipo nativo
O uniqueidentifier do SQL Server não compara os bytes da esquerda para a direita. Ele trata os últimos seis bytes como os mais significativos e depois volta pelos grupos anteriores. Um UUID v7 põe o timestamp nos primeiros seis bytes — exatamente os que o SQL Server olha por último. Então os valores v7 se espalham por um índice clustered quase tão mal quanto os v4, e o benefício evapora. Guardá-los como binary(16), ou usar um GUID no estilo COMB que põe a parte crescente no fim, é a solução de sempre.
Dentro de um mesmo milissegundo
Dois UUIDs v7 feitos no mesmo milissegundo têm timestamps idênticos, então a ordem relativa deles é decidida pelos bits aleatórios — ou seja, é arbitrária. A RFC 9562 permite gastar parte do campo aleatório em monotonicidade, seja com um contador, seja com precisão extra de relógio, e algumas implementações fazem isso: o uuidv7() embutido do PostgreSQL coloca precisão de relógio abaixo do milissegundo nesses bits. O gerador daqui não faz; ele os preenche com aleatoriedade, o que está em conformidade, mas significa que um lote de mil feitos em um milissegundo não tem ordem interna. Entre milissegundos diferentes a ordenação é exata. Se você depende da ordem dos UUIDs como critério de desempate num caminho de escrita intenso, verifique o que a sua biblioteca faz de verdade.
E a ordenação do v7 é só tão boa quanto os relógios que a produzem. Dois servidores com cem milissegundos de diferença intercalam seus IDs, e um relógio que volta atrás produz valores que ficam ordenados antes de outros escritos anteriormente. Bom o bastante para localidade de índice, não uma fonte de verdade sobre a sequência.
O v4 ainda é um padrão razoável?
Sim, para qualquer coisa que não seja uma chave primária de alto volume. É a escolha sensata há vinte anos e não parou de funcionar. Colisões não são a preocupação em nenhuma das duas versões. O limite de aniversário coloca uma chance de 50% de uma única colisão v4 em cerca de 2,7 quintilhões de identificadores; para o v7, onde só valores que compartilham o milissegundo podem colidir, são necessários cerca de 160 bilhões deles dentro desse mesmo milissegundo.
O que dá errado mesmo é uma fonte de aleatoriedade fraca. Código antigo muitas vezes montava UUIDs na mão com Math.random, que é rápido, não é criptográfico e nunca foi feito para isso. O resultado passa em qualquer validador, porque o nibble de versão continua dizendo 4 e os bits parecem os de qualquer outro UUID visto de fora. Nenhum inspetor consegue pegar isso — nem o deste site, já que ele lê bits e não tem mais nada em que se apoiar. O único jeito de saber é abrir o código e ver se ele chama a API de criptografia da plataforma.
E ULID, v1 e v6?
O ULID é anterior ao v7 e resolve o mesmo problema: 48 bits de timestamp em milissegundos mais 80 bits aleatórios, escritos como 26 caracteres de base32 de Crockford em vez de hexadecimal. É mais curto e não diferencia maiúsculas de minúsculas, mas não é um UUID, então tipos de banco de dados, validadores e ORMs não o reconhecem sem ajuda. O v7 é a versão padronizada da mesma ideia.
O v1 é o UUID original baseado em tempo: o relógio é partido em três pedaços na ordem errada para ordenar, e os últimos seis bytes são um identificador de nó que historicamente era o endereço MAC da máquina. O v6 é o v1 com esses campos reorganizados para que ordenem, e existe principalmente para permitir que sistemas que já têm valores v1 migrem. O v3 e o v5 são outra ferramenta — eles passam um namespace e um nome por uma função hash, então a mesma entrada sempre produz o mesmo UUID. Nenhum deles é a resposta certa para trabalho novo que precisa de valores únicos frescos.
Como guardar um UUID?
Como 16 bytes, não como 36 caracteres. Uma coluna CHAR(36) guarda os hífens e a grafia hexadecimal em vez do valor em si, e todo índice construído sobre ela carrega o mesmo peso morto — o que desfaz boa parte do motivo pelo qual você trocou para o v7.
O PostgreSQL tem um tipo uuid nativo. A versão 18, lançada em setembro de 2025, trouxe um uuidv7() embutido; o uuid_extract_timestamp() chegou antes, na versão 17, e agora lê valores v7 além dos v1. O MySQL não tem tipo UUID nenhum, então BINARY(16) com UUID_TO_BIN nas bordas é o arranjo de sempre. Deixe a flag de troca dessa função desligada para v7: ela troca o primeiro e o terceiro grupos de dígitos hexadecimais, que é o que um UUID v1 precisa para ordenar e exatamente o que estraga um v7. O próprio manual do MySQL diz que a troca só beneficia valores da versão 1.
Normalize a forma de texto para minúsculas e com hífens antes que ela chegue ao banco de dados, qualquer que seja o tipo escolhido. Essa é a representação canônica, e uma tabela guardando as duas grafias do mesmo identificador é uma caçada a bugs que ninguém curte.
Se você só precisa de identificadores e não de uma decisão, o gerador de UUID faz os dois tipos mil por vez e também desmonta um existente para dizer de qual versão ele é e, no caso de um v7, quando foi feito. Ele roda inteiro no seu navegador e tira a aleatoriedade do gerador criptográfico da plataforma, não do Math.random.
Uma coisa que as pessoas tentam em seguida é encurtar a forma de texto de 36 caracteres codificando os 16 bytes crus, o que desce para 22 caracteres. O que é Base64 e quando você realmente precisa dele cobre o que essa codificação faz com seus dados e por que existe a variante segura para URL — vale ler antes de colocar a forma curta numa rota.
Perguntas frequentes
Devo usar UUID v4 ou v7?
Use v7 para chaves primárias de banco de dados e para qualquer coisa que seja indexada em volume, porque o timestamp inicial faz as inserções entrarem no fim do índice em vez de se espalharem por ele. Use v4 quando o identificador é público e a hora de criação precisa ficar privada. Para IDs internos de baixo volume, qualquer um dos dois serve.
É seguro expor um UUID v7 numa URL?
Ele é impossível de adivinhar, mas não é privado. Os primeiros 48 bits são a hora de criação em milissegundos, legível por qualquer um que tenha o valor, então um ID v7 público publica quando o registro foi criado. Os 74 bits aleatórios restantes fazem com que ninguém consiga enumerar seus registros, então o único vazamento real é o timestamp.
UUIDs v7 colidem mais do que os v4?
No papel sim, na prática não. Um UUID v4 tem 122 bits aleatórios contra os 74 do v7, mas dois valores v7 só podem colidir se foram gerados no mesmo milissegundo, e chegar a uma chance de 50% disso exige cerca de 160 bilhões deles dentro desse único milissegundo. Com qualquer uma das versões o risco realista é uma fonte de aleatoriedade fraca, não a contagem de bits.
UUID v7 funciona no SQL Server?
Ele gera e armazena sem problema, mas o ganho de desempenho não sobrevive ao tipo nativo uniqueidentifier. O SQL Server compara esses valores começando pelos últimos seis bytes, e o v7 põe o timestamp nos primeiros seis, então os valores continuam caindo de forma aleatória num índice clustered. Guarde-os como binary(16) ou use um esquema de GUID sequencial feito para o SQL Server.
Qual é a diferença entre UUID v7 e ULID?
Os dois codificam a mesma ideia: um timestamp de 48 bits em milissegundos seguido de bits aleatórios. O ULID usa 80 bits aleatórios e uma forma de texto de 26 caracteres em base32, enquanto o v7 usa 74 bits aleatórios e a forma UUID padrão de 36 caracteres. O v7 faz parte da RFC 9562, então bancos de dados, validadores e bibliotecas o reconhecem nativamente; o ULID costuma precisar de tratamento extra.
Como eu sei qual versão de UUID eu tenho?
Olhe o décimo terceiro dígito hexadecimal, que é o primeiro caractere depois do segundo hífen. Ele guarda o número da versão, então um 4 ali significa um v4 aleatório e um 7 significa um v7 ordenado por tempo. O caractere depois do terceiro hífen é a variante, e é por isso que tantos UUIDs têm um 8, 9, a ou b nesse lugar.
Última atualização 19 de setembro de 2026