Generador ULID

Generar identificadores ULID

¿Por qué usar un ULID en lugar de un UUID?

Los ULID ofrecen varias ventajas sobre los UUID:

  • Ordenable lexicográficamente
  • Mejor rendimiento en BDD
  • Más corto y legible (Base32)
Estructura de un ULID

Un ULID consta de 26 caracteres:

10 caracteres para la marca de tiempo | 16 caracteres aleatorios
Entendiendo ULIDs
TL;DR

ULID combina una marca de tiempo de 48 bits con 80 bits de aleatoriedad, produciendo identificadores que son tanto únicos como ordenables cronológicamente.

¿Qué es un ULID?

Un ULID (Universally Unique Lexicographically Sortable Identifier, Identificador Universalmente Único y Lexicográficamente Ordenable) es un identificador de 128 bits diseñado para ser tanto globalmente único como ordenado por tiempo. Creado por Alizain Feerasta en 2016, los ULIDs abordan una limitación clave de los UUIDs: los UUIDs aleatorios (v4) no son ordenables, lo que causa problemas de rendimiento cuando se usan como claves primarias en bases de datos.

Un ULID codifica una marca de tiempo Unix en milisegundos en sus bits más significativos, seguida de datos criptográficamente aleatorios. Esto significa que los ULIDs generados posteriormente siempre son lexicográficamente mayores que los anteriores — se pueden ordenar como cadenas y obtener el orden cronológico de forma gratuita.

Los ULIDs se representan como cadenas de 26 caracteres usando codificación Crockford Base32, lo que los hace seguros para URLs, insensibles a mayúsculas/minúsculas y más compactos que el formato UUID de 36 caracteres.

Estructura del ULID

Un ULID tiene 128 bits en total, divididos en dos componentes:

ULID Structure Breakdown The ULID 01ARZ3NDEKTSV4RRFFQ69G5FAV split into a 10-character timestamp portion (48 bits) and a 16-character randomness portion (80 bits). ULID Structure (128 bits, Crockford Base32) 01ARZ3NDEKTSV4RRFFQ69G5FAV 01ARZ3NDEK Timestamp 48 bits (10 characters) Unix time in milliseconds Valid until 10889 AD TSV4RRFFQ69G5FAV Randomness 80 bits (16 characters) Cryptographically random Monotonic within same ms Total: 128 bits = 26 Crockford Base32 characters Lexicographic sort order = Chronological order

La marca de tiempo ocupa los primeros 48 bits (10 caracteres Crockford Base32). Almacena el número de milisegundos desde la época Unix (1 de enero de 1970). Esto le da a los ULIDs un rango válido hasta aproximadamente el año 10889.

La aleatoriedad ocupa los 80 bits restantes (16 caracteres). Cuando se generan múltiples ULIDs dentro del mismo milisegundo, las implementaciones típicamente incrementan la porción aleatoria de forma monótona para preservar el orden dentro de la misma marca de tiempo.

Codificación Crockford Base32

Los ULIDs usan Crockford Base32, un alfabeto de codificación diseñado por Douglas Crockford que está optimizado para la legibilidad humana:

0123456789ABCDEFGHJKMNPQRSTVWXYZ

Cuatro letras están deliberadamente excluidas:

  • I — se confunde con 1 o l
  • L — se confunde con 1 o I
  • O — se confunde con 0
  • U — puede formar palabras ofensivas accidentalmente

Esto hace que los ULIDs sean más seguros de leer en voz alta, transcribir manualmente y usar en URLs. La codificación es insensible a mayúsculas/minúsculas, por lo que 01ARZ3NDEK y 01arz3ndek representan el mismo valor.

ULID vs UUID vs NANOID

PropiedadUUID v4ULIDNANOIDUUID v7
Tamaño128 bits128 bitsConfigurable (126 bits por defecto)128 bits
Longitud de texto36 caracteres26 caracteres21 caracteres (por defecto)36 caracteres
CodificaciónHex + guionesCrockford Base32Base64 seguro para URLHex + guiones
OrdenableNoSí (marca de tiempo)NoSí (marca de tiempo)
Marca de tiempoNo48 bits en msNo48 bits en ms
MonótonoNoDentro del mismo msNoDentro del mismo ms
EstándarRFC 4122Spec (comunidad)Spec (comunidad)RFC 9562
EcosistemaUniversalCrecienteCentrado en JavaScriptCreciente

Cuándo Elegir ULID

Elija ULID cuando necesite identificadores ordenables y compactos y esté trabajando en un entorno donde la especificación ULID esté bien soportada. Los ULIDs son especialmente atractivos para:

  • Event sourcing — Los eventos deben estar ordenados. Las marcas de tiempo de ULID proporcionan un ordenamiento natural sin un número de secuencia separado.
  • Bases de datos distribuidas — Cassandra, DynamoDB y otros almacenes distribuidos se benefician de claves de partición ordenadas por tiempo que evitan puntos calientes.
  • Colas de mensajes — Los ULIDs como IDs de mensaje permiten a los consumidores procesar mensajes en orden cronológico aproximado.
  • Agregación de logs — Al combinar logs de múltiples servicios, los IDs de log basados en ULID se ordenan correctamente entre fuentes.

Elija UUID v7 en su lugar si necesita máxima compatibilidad con el ecosistema (las bibliotecas UUID existen en todos los lenguajes) y el formato de 36 caracteres es aceptable. UUID v7 proporciona el mismo beneficio de ordenamiento por tiempo en un formato RFC estandarizado.

Elija NANOID si necesita el identificador más corto posible y la ordenabilidad no es importante — por ejemplo, acortadores de URL o claves generadas del lado del cliente donde la compacidad es lo más importante.

ULIDs Monótonos

Al generar múltiples ULIDs dentro del mismo milisegundo, una implementación ingenua podría producir IDs con marcas de tiempo idénticas y porciones aleatorias independientes — que podrían no ordenarse en el orden de generación. Los ULIDs monótonos resuelven esto incrementando el componente aleatorio en 1 por cada ULID generado dentro del mismo milisegundo.

Esto garantiza que incluso la generación sub-milisegundo preserve un ordenamiento estricto. La mayoría de las bibliotecas ULID de producción implementan generación monótona por defecto.

La contrapartida es que los ULIDs monótonos generados en el mismo milisegundo tienen una ligera correlación en sus porciones aleatorias. En la práctica, esto no tiene impacto en la unicidad — el espacio aleatorio de 80 bits es lo suficientemente vasto como para que incluso incrementos secuenciales dentro de un solo milisegundo nunca se superpongan entre diferentes generadores.

Casos de Uso Comunes

  • Claves primarias de base de datos: Los ULIDs proporcionan la unicidad de los UUIDs con el ordenamiento amigable para índices de los enteros auto-incrementales
  • IDs de eventos en arquitecturas orientadas a eventos: El ordenamiento cronológico natural simplifica la reproducción de eventos, la depuración y las pistas de auditoría
  • Correlación en sistemas distribuidos: Servicios independientes generan IDs ordenables sin coordinación, permitiendo la correlación de logs entre servicios
  • Datos de series temporales: La marca de tiempo incorporada permite consultas aproximadas basadas en tiempo sobre el propio ID, sin una columna de marca de tiempo separada
  • Identificadores de recursos API: 26 caracteres es más compacto que los 36 del UUID, y la codificación insensible a mayúsculas/minúsculas evita problemas con URLs

Prueba estos ejemplos

ULID Válido Válido

Un ULID válido — 26 caracteres codificados en Crockford Base32. Los primeros 10 caracteres representan una marca de tiempo Unix de 48 bits en milisegundos. Los 16 caracteres restantes son criptográficamente aleatorios.

01ARZ3NDEKTSV4RRFFQ69G5FAV
Dos ULIDs Generados con 1 Segundo de Diferencia Válido

Los ULIDs generados en diferentes momentos son naturalmente ordenables. La porción de la marca de tiempo se incrementa, por lo que el ordenamiento de cadenas equivale al ordenamiento cronológico. No se necesita un comparador especial.

01ARZ3NDEK0000000000000000 < 01ARZ3NFHK0000000000000000