¿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 requisito | Mejor opción | Por qué |
|---|---|---|
| Clave primaria de base de datos (proyecto nuevo) | UUID v7 | Ordenado por tiempo, tipo de columna uuid estándar, mejor rendimiento de índice |
| ID único de propósito general (sin necesidad de orden) | UUID v4 | Soporte universal, configuración cero, 122 bits de aleatoriedad |
| ID determinista a partir de entradas conocidas | UUID v5 | El mismo espacio de nombres + nombre siempre produce el mismo UUID |
| Sistema distribuido de alto rendimiento (>100K IDs/s/nodo) | Snowflake ID | Entero de 64 bits, monotónico dentro de un worker, almacenamiento nativo BIGINT |
| Token URL-safe corto o ID del lado del cliente | NanoID | 21 caracteres, alfabeto URL-safe, longitud personalizable |
| Sistema heredado que ya usa ULID | ULID | Mantenlo — 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_atadicional - Tipo de columna
uuidestá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étrica | UUID v4 | UUID v7 | Mejora |
|---|---|---|---|
| Rendimiento de inserción (filas/s) | 12.400 | 28.600 | 2,3x más rápido |
| Tamaño del índice tras 50M filas | 4,2 GB | 2,8 GB | 33% más pequeño |
| Divisiones de páginas durante inserción masiva | 1,2M | 84K | 93% menos |
| Escaneo secuencial tras inserción | 320 ms | 180 ms | 44% 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?
| Aspecto | ULID | UUID v7 |
|---|---|---|
| Ordenable | Sí | Sí |
| Longitud de cadena | 26 caracteres | 36 caracteres |
| Almacenamiento | 16 bytes | 16 bytes |
| Estándar | Especificación de la comunidad | IETF RFC 9562 |
| Tipo nativo de DB | No (CHAR(26) o BYTEA) | Sí (uuid) |
| Soporte de lenguajes | npm, PyPI, crates.io | Integrado 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ística | UUID v4 | UUID v7 | ULID | Snowflake | NanoID |
|---|---|---|---|---|---|
| Longitud | 36 caracteres | 36 caracteres | 26 caracteres | 15-20 dígitos | 21 caracteres (por defecto) |
| Almacenamiento | 16 bytes | 16 bytes | 16 bytes | 8 bytes | ~21 bytes |
| Ordenable | No | Sí (tiempo) | Sí (tiempo) | Sí (tiempo) | No |
| Timestamp | No | 48-bit ms | 48-bit ms | 41-bit ms | No |
| Aleatoriedad | 122 bits | 74 bits | 80 bits | Secuencia de 12 bits | ~126 bits |
| Estándar | RFC 9562 | RFC 9562 | Comunidad | Propietario | Comunidad |
| Tipo nativo DB | uuid | uuid | No | BIGINT | No |
| Coordinación | Ninguna | Ninguna | Ninguna | Registro de workers | Ninguna |
| URL-safe | No (guiones) | No (guiones) | Sí | Sí (entero) | Sí |
| 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
- 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.
- Actualiza tu código de generación de IDs — cambia
uuidv4()poruuidv7()en tu capa de aplicación. - NO reescribas los IDs v4 existentes. Esto rompería las claves foráneas, las referencias externas y las URLs en caché.
- 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.