03 / GUIAS
UUID vs. ULID: escolhendo identificadores para sua aplicação
UUID v4 versus v7, estrutura e ordenabilidade do ULID, o que identificadores aleatórios fazem com um índice B-tree, probabilidade de colisão, exposição em URLs e geração de identificadores localmente.
O que um identificador de aplicação precisa fazer
Um identificador gerado tem um único trabalho — ser único — mais alguns que ele adquire no caminho: gerar em qualquer lugar sem coordenação, armazenar de forma compacta, ordenar previsivelmente e não vazar nada embaraçoso. UUID e ULID passam no teste de unicidade; divergem em tudo que vem depois.
- Sem coordenaçãoGeração descentralizada: qualquer serviço, worker ou aba de navegador pode cunhar um identificador sem pedir a um contador central, e é isso que faz os dois formatos servirem a sistemas distribuídos.
- Os mesmos 128 bits128 bits de qualquer jeito: um UUID é um valor de 128 bits escrito como 36 caracteres hexadecimais com hífens; um ULID carrega os mesmos 128 bits como 26 caracteres base32.
- O layout é a diferençaA pergunta real é o layout: quais bits são aleatórios e quais codificam tempo decide como o identificador se comporta num índice e o que ele revela.
Versões de UUID: v4 é aleatório, v7 é ordenado por tempo
A RFC 9562 define várias versões de UUID, mas duas dominam o trabalho de aplicações. A versão 4 preenche 122 dos 128 bits com aleatoriedade e não embute mais nada; a versão 7 abre com um timestamp Unix de 48 bits em milissegundos e preenche os 74 bits restantes com aleatoriedade.
- v4: aleatório purov4 é a escolha de privacidade máxima: o valor não diz nada sobre quando ou onde foi criado, e 122 bits aleatórios são mais unicidade do que qualquer aplicação vai gastar.
- v7: tempo primeirov7 se ordena principalmente pelo carimbo de tempo em milissegundos. A ordem dentro do mesmo milissegundo e entre dispositivos depende do gerador e dos relógios.
- Pule a v1Versões mais antigas são legado: v1 embutia um endereço MAC e um valor de relógio, vazando ambos; v3 e v5 são hashes baseados em nome para derivar IDs estáveis, não aleatoriedade nova.
ULID: ordenável e compacto como texto
Um ULID tem 26 caracteres de base32 Crockford: os primeiros 10 caracteres codificam um timestamp de 48 bits em milissegundos, os 16 restantes codificam 80 bits aleatórios. O alfabeto exclui deliberadamente I, L, O e U, então identificadores sobrevivem a ser lidos em voz alta ou digitados de uma captura de tela.
- Ordenação de string = ordenação temporalOrdem lexicográfica é ordem temporal: ordenar ULIDs como strings puras os ordena por tempo de criação sem análise — útil em linhas de log, nomes de arquivo e armazenamentos chave-valor.
- 26 caracteres segurosCompacto e seguro para URL: 26 caracteres sem distinção de maiúsculas, sem hífens nem símbolos, mais curto que os 36 de um UUID e seguro em qualquer segmento de caminho ou parâmetro de consulta.
- Monotônico por milissegundoDentro de um mesmo milissegundo, a ordenação vem da parte aleatória; geradores que a incrementam monotonicamente — como o gerador em lote do Toolars — mantêm até identificadores do mesmo milissegundo em ordem de geração.
IDs aleatórios fragmentam seus índices
Um índice B-tree é ordenado, e inserir um UUID v4 aleatório escreve numa folha aleatória toda vez: páginas se dividem, o cache de buffer se agita e o índice incha com espaço morto. Identificadores ordenados por tempo anexam perto da borda direita do índice, transformando inserções no melhor caso do B-tree.
É por isso que a escolha pertence à hora de desenhar o esquema, não depois do primeiro trimestre lento: migrar uma chave primária significa reescrever cada linha e cada chave estrangeira que a referencia. Se a tabela vai ficar pequena, a desordem do v4 nunca aparece; se vai crescer a centenas de milhões de linhas sob escritas constantes, os formatos ordenados pagam o aluguel desde o primeiro dia.
- Aleatório dispersaCom v4 como chave primária, tabelas com muitas inserções mostram mais divisões de página, fatores de preenchimento menores e throughput de escrita mensuravelmente pior do que com uma chave ordenada do mesmo tamanho.
- Ordenado anexav7 e ULID melhoram a localidade do índice sem coordenação central. IDs vizinhos em um lote monotônico podem ser previsíveis; imponha autorização independentemente do identificador.
- Meça a trocaA troca é real, mas modesta: 128 bits são o dobro do armazenamento de um bigint, e chaves ordenadas por tempo concentram as escritas de hoje na borda direita do índice, o que só importa em taxas de inserção muito altas.
Colisões, URLs e o que um ID revela
Com 122 bits aleatórios independentes em v4, um bilhão de identificadores tem probabilidade de colisão de cerca de um em 10^19. Os 80 bits aleatórios do ULID protegem outro orçamento: identificadores criados no mesmo milissegundo.
Cole qualquer valor suspeito no validador: ele reconhece a forma canônica de UUID de 36 caracteres com sua variante RFC 9562 e seu nibble de versão, o alfabeto ULID de 26 caracteres com sua regra de overflow, e relata o timestamp embutido nos formatos ordenados por tempo — então um valor de um log diz o que é antes de você construir sobre ele.
- Probabilidade desprezívelNenhum dos formatos é um limite de segurança: um identificador numa URL serve para endereçamento, mas qualquer pessoa que o vê pode citá-lo — a autorização precisa vir de verificações de acesso, não da opacidade do ID.
- IDs não são segredosv7 e ULID vazam o tempo de criação por design; o validador o extrai abertamente. Isso normalmente é metadado inofensivo, mas decida conscientemente para objetos voltados ao público.
- O tempo fica visívelIDs sequenciais de banco vazam volume e taxa de crescimento; identificadores aleatórios e tempo-aleatórios não revelam nada sobre quantos registros existem.
Gere e valide sem um servidor
A geração de identificadores precisa de exatamente um recurso escasso — boa aleatoriedade — e o navegador já o tem. O espaço de trabalho tira de crypto.getRandomValues, gera lotes inteiramente na aba e nunca transmite um valor.
- 1–100 por loteEscolha UUID v4, UUID v7 ou ULID e gere de 1 a 100 por lote; lotes de v7 e ULID incrementam o campo aleatório monotonicamente, então um lote inteiro permanece em ordem de geração.
- Caixa e exportaçãoA caixa da saída é uma escolha de exibição: canônica, maiúscula ou minúscula, com copiar tudo e downloads em texto delimitado por quebra de linha e CSV que registram o tempo embutido de cada identificador.
- Validação instantâneaA validação responde perguntas de estrutura instantaneamente: comprimento, alfabeto, versão e variante de UUID, valores especiais nil e max, overflow de ULID e o timestamp embutido em UTC.
ULID é base32; seus tokens provavelmente são Base64.
Codificações de bytes para texto estão por baixo de cada identificador e token — aprenda quanto custam e onde justificam seu lugar.