UUID v4 vs UUID v7: cuál usar como llave primaria
Última actualización: 8 de octubre de 2026
Durante años "usa UUID v4" fue la respuesta por defecto para identificadores únicos. Desde que el estándar RFC 9562 (2024) formalizó UUID v7, la pregunta correcta ya no es si usar UUID, sino cuál versión usar y para qué. La diferencia se nota sobre todo en el rendimiento de las bases de datos con muchas escrituras, y en lo que el identificador revela sobre ti.
Qué tienen en común y qué cambia
Ambas versiones son identificadores de 128 bits con el mismo formato de texto (32 caracteres hexadecimales con guiones, 36 en total), y ambas están definidas en el RFC 9562, que reemplaza al RFC 4122. La probabilidad de colisión es despreciable en las dos: en un UUID v4, con 122 bits aleatorios, tendrías que generar del orden de 2.7 × 10¹⁸ identificadores para tener un 50% de probabilidad de una sola colisión.
Lo que cambia es la estructura interna. Un UUID v4 es casi todo aleatorio: salvo unos pocos bits que indican versión y variante, el resto son bits criptográficamente aleatorios. Un UUID v7 empieza con una marca de tiempo de 48 bits (milisegundos desde el 1 de enero de 1970, época Unix) seguida de bits aleatorios. Esto hace que los UUID v7 generados en momentos distintos se ordenen cronológicamente al compararlos como cadenas o como bytes.
Por qué importa para las bases de datos
La mayoría de los índices de bases de datos son árboles B. Cuando insertas una fila con un identificador aleatorio (v4), el nuevo valor cae en una posición cualquiera del índice. Con tablas grandes eso provoca divisiones de páginas, fragmentación y más lecturas de disco o de caché, porque cada inserción toca una parte distinta del árbol. En motores donde la llave primaria define el orden físico de la tabla (como InnoDB en MySQL), el efecto es todavía más marcado.
Con UUID v7 las inserciones nuevas tienen prefijo de tiempo creciente, así que caen cerca del final del índice, igual que un entero autoincremental. Se conserva la ventaja de poder generar el identificador en la aplicación sin consultar a la base de datos, y se evita buena parte del costo de escritura de la aleatoriedad pura. La diferencia es despreciable con tablas pequeñas y empieza a notarse cuando la tabla es grande y recibe muchas escrituras.
La contrapartida: v7 revela cuándo se creó
Como los primeros 48 bits de un UUID v7 son la hora de creación, cualquiera que vea el identificador puede extraer cuándo se generó, con precisión de milisegundos. Normalmente no importa, pero puede ser un problema si el identificador es público y no quieres revelar el momento de creación de un registro, o si alguien puede inferir tu volumen de registros o pedidos comparando identificadores a lo largo del tiempo.
Un UUID v4 no revela nada de eso. Por esa razón se sigue prefiriendo v4 para identificadores que se exponen hacia fuera y deben ser opacos: tokens, enlaces de invitación, claves de API, identificadores de sesión. Aquí además conviene recordar que un identificador no es un secreto por sí mismo: para tokens de seguridad la fuente de aleatoriedad debe ser criptográficamente segura, lo que ya cumple crypto.randomUUID() en el navegador.
Soporte actual
PostgreSQL 18, publicado a finales de septiembre de 2025, incluye una función nativa uuidv7() y permite extraer la marca de tiempo de un UUID con uuid_extract_timestamp(). Python 3.14 añadió uuid.uuid7() a su módulo estándar, y el paquete uuid de npm también soporta la versión 7. En versiones anteriores de las bases de datos y lenguajes puedes generarlos con una biblioteca o una extensión.
Un punto a tener en cuenta en el navegador: crypto.randomUUID() genera siempre UUID v4. Si necesitas v7 del lado del cliente, hace falta una biblioteca o implementarlo siguiendo el RFC. Y sea cual sea la versión, almacena el UUID en el tipo nativo de tu base de datos (uuid en PostgreSQL, BINARY(16) en MySQL) en lugar de como texto: son 16 bytes frente a 36 caracteres, y los índices son mucho más compactos.
Una regla práctica para elegir
Si el identificador es una llave primaria en una tabla que recibe muchas escrituras, o quieres poder ordenar por creación sin una columna extra, elige UUID v7. Si el identificador se expone públicamente y debe ser opaco, o la hora de creación no debe filtrarse, elige UUID v4. Si la tabla es pequeña o de pocas escrituras, cualquiera de las dos funciona y la decisión no es importante.
Un matiz honesto: el orden de UUID v7 es por milisegundo. Dos identificadores generados en el mismo milisegundo, o en máquinas distintas con relojes ligeramente desfasados, no están garantizados en orden estricto a menos que la implementación incluya un contador monótono. Para ordenar con certeza por creación, mantén una columna de fecha además del identificador.
Preguntas frecuentes
- ¿Puedo mezclar UUID v4 y v7 en la misma tabla?
- Técnicamente sí, porque ambos son UUID válidos de 128 bits. Pero mezclar degrada la ventaja de ordenamiento de v7, ya que los v4 caerán en posiciones aleatorias del índice. Lo habitual es elegir una versión por tabla.
- ¿UUID v7 es más seguro que v4?
- No. Es una cuestión de organización de los datos, no de seguridad. De hecho v7 tiene menos bits aleatorios (74 frente a 122) y revela la hora de creación, así que para tokens o identificadores sensibles v4 es la mejor opción.
- ¿Sigue siendo válido usar UUID v4 como llave primaria?
- Sí. Para tablas pequeñas o con pocas escrituras la diferencia de rendimiento es irrelevante, y v4 sigue siendo la versión más soportada y entendida en todo el ecosistema.
- ¿Es mejor un entero autoincremental?
- En una sola base de datos suele ser lo más compacto y rápido. Los UUID ganan cuando necesitas generar identificadores sin consultar a la base de datos, combinar datos de varios sistemas o no exponer cuántos registros tienes.
- ¿El generador de UUID de este sitio qué versión crea?
- UUID v4, usando crypto.randomUUID() con una fuente criptográficamente segura. Es la versión apropiada para identificadores públicos, tokens e identificadores de prueba.