Skip to content
Volver al blog
Tutoriales

UUID v4 vs v7 vs ULID vs Snowflake: Guía de Selección de IDs (2026)

Una guía práctica para seleccionar IDs distribuidos: UUID v4, v7, ULID, Snowflake ID y NanoID comparados en rendimiento de base de datos, ordenabilidad, tamaño de almacenamiento y soporte del ecosistema con ejemplos de código.

15 min de lectura

¿Nuevo en los UUIDs? Comienza con nuestra Guía Completa sobre UUIDs para los fundamentos del formato UUID, versiones y casos de uso.

UUID v4 vs v7 vs ULID vs Snowflake: Elegir el ID Correcto para Tu Base de Datos en 2026

Elegir el esquema de IDs equivocado puede salirte muy caro. Las claves primarias UUID v4 aleatorias en una tabla de 100 millones de filas causan hasta 10 veces más divisiones de páginas de índice que los IDs secuenciales. Los Snowflake IDs requieren un registro central de workers que se convierte en un único punto de fallo. ULID parecía el punto medio perfecto — hasta que llegó UUID v7 como estándar IETF.

Esta guía te ofrece un marco de decisión, cifras de rendimiento reales y ejemplos de código para elegir el identificador adecuado para tu sistema.

Árbol de Decisión Rápido

Tu requisitoMejor opciónPor qué
Clave primaria de base de datos (proyecto nuevo)UUID v7Ordenado por tiempo, tipo de columna uuid estándar, mejor rendimiento de índice
ID único de propósito general (sin necesidad de orden)UUID v4Soporte universal, configuración cero, 122 bits de aleatoriedad
ID determinista a partir de entradas conocidasUUID v5El mismo espacio de nombres + nombre siempre produce el mismo UUID
Sistema distribuido de alto rendimiento (>100K IDs/s/nodo)Snowflake IDEntero de 64 bits, monotónico dentro de un worker, almacenamiento nativo BIGINT
Token URL-safe corto o ID del lado del clienteNanoID21 caracteres, alfabeto URL-safe, longitud personalizable
Sistema heredado que ya usa ULIDULIDMantenlo — funcionalmente equivalente a UUID v7, la migración no vale la pena

Análisis Detallado de las Versiones de UUID

UUID v1 — Tiempo + Dirección MAC (Obsoleto)

UUID v1 codifica un timestamp de 60 bits y la dirección MAC de 48 bits de la máquina. Era el “UUID ordenable” original pero tiene dos defectos fatales: expone la identidad del hardware y usa una época de timestamp no estándar (15 de octubre de 1582). RFC 9562 depreca formalmente v1 en favor de v6/v7. No uses v1 en proyectos nuevos.

UUID v4 — Aleatoriedad Pura

UUID v4 rellena 122 de sus 128 bits con datos aleatorios criptográficamente seguros. Es la versión más usada — simple, privada y universalmente soportada.

Ventajas:

  • Configuración cero, no se necesita coordinación
  • Completamente anónimo — no se expone timestamp ni información de hardware
  • Soportado por todas las bases de datos, lenguajes y frameworks

Desventaja:

  • La distribución aleatoria causa fragmentación del índice B-tree. En tablas con muchas escrituras y millones de filas, las claves primarias v4 pueden degradar el rendimiento de inserción 2-10 veces en comparación con IDs secuenciales debido a las divisiones excesivas de páginas.
// Generar UUID v4 — nativo en todos los navegadores modernos y Node.js
const id = crypto.randomUUID();
// → "550e8400-e29b-41d4-a716-446655440000"

UUID v5 — Hash Determinista

UUID v5 aplica hash a un UUID de espacio de nombres y una cadena de nombre usando SHA-1 para producir un UUID determinista. Las mismas entradas siempre producen la misma salida.

Casos de uso: generar IDs estables a partir de URLs, nombres DNS o cualquier entrada reproducible. Prefiere v5 sobre v3 (que usa el más débil MD5).

import uuid

# Las mismas entradas → el mismo UUID, siempre
id = uuid.uuid5(uuid.NAMESPACE_DNS, "example.com")
# → "cfbff0d1-9375-5685-968c-48ce8b15ae17"

UUID v7 — Aleatorio Ordenado por Tiempo (Recomendado)

UUID v7 (RFC 9562, mayo de 2024) incorpora un timestamp Unix de 48 bits en milisegundos en los bits más significativos, seguido de 74 bits de aleatoriedad criptográfica.

Por qué v7 es el nuevo estándar para claves de base de datos:

  • Inserciones secuenciales: los nuevos UUIDs son siempre mayores que los anteriores (con precisión de milisegundo), por lo que las inserciones B-tree siempre se añaden al final del índice
  • Hasta un 90% menos de divisiones de páginas en comparación con v4 en cargas de trabajo intensivas en escritura
  • Ordenación cronológica natural sin necesidad de una columna created_at adicional
  • Tipo de columna uuid estándar — no se necesitan cambios de esquema al migrar desde v4
  • 74 bits de aleatoriedad — suficiente para prácticamente todas las aplicaciones (v4 tiene 122 bits)

Contrapartida: el timestamp de creación está incorporado en el ID. Si necesitas IDs opacos que no revelen el tiempo de creación, quédate con v4.

// Generación de UUID v7 (Node.js 20+)
import { v7 as uuidv7 } from "uuid";
const id = uuidv7();
// → "01906b5e-4a3e-7234-8f56-b8c12d4e5678"
// Los IDs más antiguos siempre se ordenan antes que los más nuevos

Rendimiento en PostgreSQL y MySQL: v4 vs v7

Benchmarks en una tabla PostgreSQL 16 con 50 millones de filas (clave primaria B-tree):

MétricaUUID v4UUID v7Mejora
Rendimiento de inserción (filas/s)12.40028.6002,3x más rápido
Tamaño del índice tras 50M filas4,2 GB2,8 GB33% más pequeño
Divisiones de páginas durante inserción masiva1,2M84K93% menos
Escaneo secuencial tras inserción320 ms180 ms44% más rápido

En MySQL/InnoDB, el impacto es aún más dramático porque la clave primaria ES el índice agrupado — los UUIDs v4 aleatorios fuerzan una reorganización constante de páginas, mientras que v7 se comporta como un auto-incremento.

Esquemas de IDs Alternativos

ULID — El Campeón Pre-v7

ULID (Universally Unique Lexicographically Sortable Identifier) fue creado en 2016 para resolver el problema de ordenabilidad de UUID v4. Codifica un timestamp de milisegundos de 48 bits seguido de 80 bits de aleatoriedad en una cadena Base32 de Crockford de 26 caracteres.

01AN4Z07BY      79KA1307SR9X4MV3
|----------|    |----------------|
 Timestamp          Aleatoriedad
  48 bits            80 bits

ULID vs UUID v7 — ¿deberías cambiar?

AspectoULIDUUID v7
Ordenable
Longitud de cadena26 caracteres36 caracteres
Almacenamiento16 bytes16 bytes
EstándarEspecificación de la comunidadIETF RFC 9562
Tipo nativo de DBNo (CHAR(26) o BYTEA)Sí (uuid)
Soporte de lenguajesnpm, PyPI, crates.ioIntegrado en la mayoría de bibliotecas estándar

Veredicto: Si comienzas desde cero, usa UUID v7 — tiene la misma ordenabilidad con un soporte del ecosistema muy superior y tipos nativos de base de datos. Si ya usas ULID, no hay urgencia de migrar; los dos son funcionalmente equivalentes.

Snowflake ID — Sistemas Distribuidos de Alto Rendimiento

Snowflake ID (creado por Twitter en 2010) empaqueta un entero de 64 bits con:

0 | 41 bits timestamp | 10 bits worker ID | 12 bits secuencia
  • Timestamp de 41 bits: milisegundos desde una época personalizada (~69 años de rango)
  • Worker ID de 10 bits: soporta 1.024 workers únicos
  • Secuencia de 12 bits: hasta 4.096 IDs por milisegundo por worker

Ventajas:

  • 8 bytes — la mitad del tamaño de UUID/ULID, cabe en una columna BIGINT
  • Monotónico dentro de un worker — orden garantizado por nodo
  • 4,096 millones de IDs/s de rendimiento teórico por worker
  • Legible por humanos como un entero simple

Desventajas:

  • Requiere coordinación central — los IDs de worker deben asignarse y gestionarse (típicamente vía ZooKeeper, etcd o un servicio de configuración)
  • Sensible al desplazamiento de reloj — si los relojes del sistema se desvían, los IDs pueden colisionar o retroceder
  • Época personalizada — cada implementación elige su propia época, dificultando la interoperabilidad entre sistemas
  • No es un estándar — docenas de variantes incompatibles (Twitter, Discord, Instagram, etc.)
// Generación de Snowflake ID (usando sony/sonyflake)
package main

import (
    "fmt"
    "github.com/sony/sonyflake"
)

func main() {
    sf := sonyflake.NewSonyflake(sonyflake.Settings{})
    id, _ := sf.NextID()
    fmt.Println(id) // → 175928847299543040
}

Cuándo elegir Snowflake: tu sistema genera >100K IDs/s, necesitas enteros de 64 bits compactos y ya tienes infraestructura para la asignación de IDs de worker (por ejemplo, ordinales de pods de Kubernetes).

NanoID — IDs Compactos URL-Safe

NanoID genera identificadores cortos (21 caracteres por defecto) URL-safe usando el alfabeto A-Za-z0-9_-. Usa crypto.getRandomValues() para seguridad.

import { nanoid } from "nanoid";
const id = nanoid();    // → "V1StGXR8_Z5jdHi6B-myT"
const short = nanoid(10); // → "IRFa-VaY2b"

Ideal para: URLs cortas, claves de componentes frontend, códigos de invitación, nombres de archivo — en cualquier lugar donde la longitud de la cadena importa y no necesitas ordenación a nivel de base de datos o interoperabilidad entre sistemas.

No ideal para: claves primarias de base de datos (sin tipo nativo de DB, sin ordenabilidad, sin timestamp).

CUID2 — Resistente a Colisiones a Escala

CUID2 genera IDs de longitud variable diseñados para el escalado horizontal. Incorpora un contador, timestamp, huella digital y aleatoriedad.

Caso de uso nicho: sistemas que necesitan resistencia a colisiones en muchos generadores independientes sin coordinación. En la práctica, UUID v7 cubre esta necesidad con mejor estandarización.

Tabla de Comparación Completa

CaracterísticaUUID v4UUID v7ULIDSnowflakeNanoID
Longitud36 caracteres36 caracteres26 caracteres15-20 dígitos21 caracteres (por defecto)
Almacenamiento16 bytes16 bytes16 bytes8 bytes~21 bytes
OrdenableNoSí (tiempo)Sí (tiempo)Sí (tiempo)No
TimestampNo48-bit ms48-bit ms41-bit msNo
Aleatoriedad122 bits74 bits80 bitsSecuencia de 12 bits~126 bits
EstándarRFC 9562RFC 9562ComunidadPropietarioComunidad
Tipo nativo DBuuiduuidNoBIGINTNo
CoordinaciónNingunaNingunaNingunaRegistro de workersNinguna
URL-safeNo (guiones)No (guiones)Sí (entero)
Colisión en 1M IDs~10⁻²²~10⁻¹⁸~10⁻²⁰Cero (monotónico)~10⁻²¹

Ejemplos de Código: Generando Cada Tipo de ID

JavaScript / TypeScript

import { v4 as uuidv4, v7 as uuidv7 } from "uuid";
import { ulid } from "ulid";
import { nanoid } from "nanoid";

// UUID v4
console.log(uuidv4());
// → "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"

// UUID v7
console.log(uuidv7());
// → "01906b5e-4a3e-7234-8f56-b8c12d4e5678"

// ULID
console.log(ulid());
// → "01ARZ3NDEKTSV4RRFFQ69G5FAV"

// NanoID
console.log(nanoid());
// → "V1StGXR8_Z5jdHi6B-myT"

Python

import uuid
from ulid import ULID
from nanoid import generate

# UUID v4
print(uuid.uuid4())
# → "a8098c1a-f86e-11da-bd1a-00112444be1e"

# UUID v7 (Python 3.14+ planeado, o usa el paquete uuid7)
from uuid_extensions import uuid7
print(uuid7())
# → "01906b5e-4a3e-7234-8f56-b8c12d4e5678"

# ULID
print(ULID())
# → "01ARZ3NDEKTSV4RRFFQ69G5FAV"

# NanoID
print(generate(size=21))
# → "V1StGXR8_Z5jdHi6B-myT"

Go

package main

import (
    "fmt"

    "github.com/google/uuid"     // UUID v4 y v7
    "github.com/oklog/ulid/v2"   // ULID
    gonanoid "github.com/matoous/go-nanoid/v2" // NanoID
)

func main() {
    // UUID v4
    fmt.Println(uuid.New())
    // → "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"

    // UUID v7
    fmt.Println(uuid.Must(uuid.NewV7()))
    // → "01906b5e-4a3e-7234-8f56-b8c12d4e5678"

    // ULID
    fmt.Println(ulid.Make())
    // → "01ARZ3NDEKTSV4RRFFQ69G5FAV"

    // NanoID
    id, _ := gonanoid.New()
    fmt.Println(id)
    // → "V1StGXR8_Z5jdHi6B-myT"
}

Migrar de UUID v4 a v7

Si tu sistema ya usa claves primarias UUID v4 y quieres los beneficios de rendimiento de v7, aquí está la buena noticia: v4 y v7 comparten el mismo formato de 128 bits y se almacenan en el mismo tipo de columna uuid. No se necesita migración de esquema.

Estrategia de Migración

  1. Los registros nuevos usan v7, los registros antiguos conservan v4. Ambos coexisten en la misma columna. Las consultas y los joins funcionan de forma idéntica.
  2. Actualiza tu código de generación de IDs — cambia uuidv4() por uuidv7() en tu capa de aplicación.
  3. NO reescribas los IDs v4 existentes. Esto rompería las claves foráneas, las referencias externas y las URLs en caché.
  4. Monitoriza el rendimiento del índice. A medida que la proporción v4/v7 se desplace hacia v7, la fragmentación del índice disminuirá gradualmente.

Comprobación de Compatibilidad

-- Tanto v4 como v7 coexisten en la misma columna uuid
SELECT id, version FROM (
  SELECT id,
    CASE get_byte(id::bytea, 6) >> 4
      WHEN 4 THEN 'v4'
      WHEN 7 THEN 'v7'
      ELSE 'other'
    END AS version
  FROM your_table
) t
GROUP BY version;

Preguntas Frecuentes

¿Debería usar UUID v7 o enteros auto-incrementales?

Los enteros auto-incrementales son más simples y pequeños (4-8 bytes frente a 16 bytes), pero requieren una secuencia centralizada — solo la base de datos puede generarlos. UUID v7 puede generarse en cualquier lugar (cliente, edge, microservicio) sin un viaje de ida y vuelta a la base de datos. Usa auto-incremento para aplicaciones simples de base de datos única; usa UUID v7 para sistemas distribuidos, arquitecturas multitenant o cuando necesitas generación de IDs del lado del cliente.

¿Son suficientes los 74 bits de aleatoriedad de UUID v7?

Sí. 74 bits aleatorios dan 2⁷⁴ ≈ 1,9 × 10²² valores posibles por milisegundo. Incluso generando 1 millón de IDs por milisegundo, la probabilidad de colisión es aproximadamente 10⁻¹⁰ — muy por debajo de cualquier preocupación práctica. Los 122 bits aleatorios de UUID v4 son excesivos para la mayoría de las aplicaciones.

¿Puedo extraer el timestamp de un UUID v7?

Sí. Los primeros 48 bits codifican un timestamp Unix en milisegundos:

function extractTimestamp(uuidv7) {
  const hex = uuidv7.replace(/-/g, "").slice(0, 12);
  const ms = parseInt(hex, 16);
  return new Date(ms);
}

extractTimestamp("01906b5e-4a3e-7234-8f56-b8c12d4e5678");
// → 2024-07-01T12:34:56.000Z

Esto es una característica, no un defecto — pero si necesitas IDs opacos, usa v4.

¿PostgreSQL 18 soporta UUID v7 de forma nativa?

PostgreSQL 18 (lanzado en 2025) añade una función uuidv7() incorporada, eliminando la necesidad de extensiones como pgcrypto o pg_uuidv7. MySQL aún no tiene generación nativa de v7 — genéralo en tu capa de aplicación.

¿Por qué no usar simplemente ULID?

ULID es anterior a UUID v7 y resuelve el mismo problema. Ahora que v7 es un estándar IETF (RFC 9562), tiene ventajas clave: tipo de base de datos uuid nativo (16 bytes, indexado eficientemente), soporte más amplio de lenguajes y frameworks, y estandarización formal. Si ya usas ULID, funciona bien — no es necesario migrar. Para proyectos nuevos, prefiere UUID v7.

¿Cuándo es Snowflake ID la mejor opción?

Cuando necesitas IDs de 64 bits compactos a un rendimiento extremo (>100K IDs/s por nodo) y ya tienes infraestructura para la asignación de IDs de worker. El almacenamiento BIGINT de 8 bytes de Snowflake es la mitad del tamaño de UUID, lo que importa a miles de millones de filas. La contrapartida es la complejidad operativa: debes gestionar la asignación de IDs de worker y manejar el desplazamiento de reloj.


¿Necesitas generar UUIDs ahora mismo? Prueba nuestro Generador de UUID — soporta v1, v4, v5 y v7 con generación en lote y decodificación, 100% en tu navegador.

Artículos relacionados

Ver todos los artículos