Cuando PostgreSQL 18 apareció el 25 de septiembre de 2025, los titulares se los llevó el subsistema de I/O asincrónico. Un año después, con la rama estable ya en 18.6 (publicada el 13 de agosto de 2026) y PostgreSQL 19 todavía en beta, el panorama cambió: PG18 dejó de ser la novedad brillante para convertirse en la versión madura que conviene adoptar. Y las tres funciones que mejor envejecieron no son las más ruidosas, sino tres cambios silenciosos que le tocan la vida diaria a cualquiera que corra una base en producción: skip scan en índices B-tree, la función nativa uuidv7() y las estadísticas del planificador que por fin sobreviven al upgrade mayor.
PostgreSQL 18 es la versión mayor del motor de base de datos relacional de código abierto que el PostgreSQL Global Development Group lanzó el 25 de septiembre de 2025. Incorpora skip scan en índices B-tree multicolumna, la función uuidv7() para identificadores ordenados por tiempo, estadísticas del optimizador que persisten a través de pg_upgrade y un subsistema de I/O asincrónico (AIO) configurable con io_method. Su minor estable actual es 18.6.
¿Conviene migrar a PostgreSQL 18 a esta altura de 2026?
Sí: hoy PostgreSQL 18 es el punto dulce. Lleva un año de parches acumulados —ya vas por la minor 18.6, publicada el 13 de agosto de 2026— y PostgreSQL 19 sigue en fase beta (la Beta 3 salió ese mismo día), sin fecha final estable. Migrar a 18 ahora te da las funciones nuevas sin ser conejillo de indias de una rama que todavía se está estabilizando.
La rama 18.x es de soporte largo, así que el esfuerzo de actualizar rinde por años. Como resumió Jonathan Katz, del core team de PostgreSQL, en el anuncio oficial: "PostgreSQL 18 se apoya en la larga y rica historia del proyecto de entregar una experiencia de gestión de datos confiable y robusta, mientras sigue expandiendo las cargas de trabajo que puede soportar". Menos épica y más práctica: si venías postergando el salto desde 16 o 17, este es el momento.
¿Qué es el skip scan en índices B-tree y qué problema resuelve?
El skip scan permite que el planificador use un índice B-tree multicolumna aunque tu consulta no filtre por la primera columna del índice. Antes, un índice sobre (a, b, c) era inútil si no ponías una condición sobre a: PostgreSQL caía a un sequential scan. Con PG18, el planner "salta" por los valores distintos de la columna líder y aprovecha el índice igual.
El caso clásico es este. Tenés el índice:
CREATE INDEX idx_orders ON orders (status, customer_id, order_date);Y una consulta que ignora status:
SELECT * FROM orders
WHERE customer_id = 123
AND order_date > '2025-01-01';Antes de PG18 eso era un sequential scan sobre toda la tabla. Ahora el planificador reescribe internamente la búsqueda recorriendo cada valor distinto de status y buscando dentro de cada uno, algo así como un UNION ALL implícito por cada valor de la columna omitida.
La letra chica importa, y conviene tenerla clara antes de tirar índices a la basura:
- Funciona bien cuando la columna líder omitida tiene baja cardinalidad. Si
statustiene 4 o 5 valores posibles, probar cada uno cuesta poco. Si tuviera millones de valores distintos, el skip scan pierde sentido y el planner probablemente elija otra estrategia. - Requiere al menos una condición de igualdad sobre una columna posterior del índice. No es magia total: necesitás un
=en alguna columna que venga después de la omitida para que el salto valga la pena. - No reemplaza al índice bien diseñado. Si una consulta es crítica, un índice con el orden de columnas correcto sigue ganándole a apoyarse en el skip scan. Pensalo como una red de contención, no como excusa para no indexar.
El efecto práctico: menos índices redundantes. Donde antes creabas un índice extra solo para cubrir consultas que omitían la primera columna, ahora quizás alcance con uno solo. Si venís de leer "Cómo elegir índices B-tree, GIN y GiST en PostgreSQL", esta función es la que te deja consolidar la biblioteca de índices que tenías inflada.
¿Para qué sirve la función uuidv7() y en qué mejora a uuidv4?
uuidv7() genera UUID ordenados por tiempo: el timestamp va al principio del identificador, así que dos IDs creados con segundos de diferencia quedan casi contiguos. Eso ataca directamente el dolor de cabeza de usar uuidv4() (aleatorio) como clave primaria: la fragmentación del índice B-tree.
El problema de los UUID v4 es conocido por cualquiera que los haya usado como PK a escala. Al ser completamente aleatorios, cada inserción cae en una página distinta del índice, lo que dispersa la escritura, infla el índice y arruina la localidad de caché. Un UUID v7, al estar ordenado por tiempo, hace que las inserciones nuevas caigan juntas —parecido a lo que lograbas con un bigserial, pero sin exponer un contador secuencial ni depender de una secuencia centralizada.
Lo relevante de PG18 es que ahora es nativo: no dependés de una extensión ni de generar el valor en la aplicación.
- Generás el ID desde SQL con
uuidv7(). Podés usarlo comoDEFAULTde una columnauuidy olvidarte de generarlo en el backend. uuidv4()también entró como alias degen_random_uuid(). Según el anuncio oficial de la versión, PG18 sumóuuidv4()como alias, así tenés nomenclatura consistente entre ambas variantes.- Mejor comportamiento de caché e índice. El anuncio del proyecto describe los UUID v7 como "ordenados por timestamp para soportar mejores estrategias de caché". En tablas con inserciones intensivas, eso se traduce en índices más compactos y menos I/O.
Una advertencia honesta: el orden temporal de un UUID v7 revela aproximadamente cuándo se creó el registro. Para claves internas no suele importar; si el ID es público y la fecha de creación es sensible, tenelo en cuenta.
¿Cómo evita PostgreSQL 18 la caída de performance después de un upgrade?
PostgreSQL 18 conserva las estadísticas del optimizador al hacer un upgrade mayor con pg_upgrade. Antes, esas estadísticas no se trasladaban: apenas terminaba el upgrade, el planificador quedaba a ciegas y elegía planes malos hasta que un ANALYZE completo reconstruía las estadísticas. En bases grandes y ocupadas, esa ventana era exactamente el peor momento para tener consultas lentas.
Este es probablemente el cambio menos vistoso y el que más agradecés en producción. La documentación oficial lo plantea sin vueltas: mantener las estadísticas del planificador a través del upgrade "ayuda a que un clúster actualizado alcance el rendimiento esperado más rápido". En criollo: menos sustos post-migración.
- Terminás el upgrade con el planner ya informado. No hay ventana ciega en la que cada consulta compleja improvisa un plan sin datos de distribución.
- Reduce la urgencia del
ANALYZEmasivo inmediato. Igual conviene correrANALYZEpara refrescar, pero deja de ser una carrera contra la degradación. - Baja el riesgo de migrar bases grandes. Uno de los grandes miedos de saltar de versión mayor —"¿se me va a caer la performance apenas prenda?"— queda muy mitigado.
¿Qué es el I/O asincrónico (AIO) que trae PostgreSQL 18?
El AIO es el nuevo subsistema que permite a PostgreSQL emitir varias operaciones de lectura contra el almacenamiento sin bloquear el proceso esperando cada una. Beneficia sobre todo a sequential scans, bitmap heap scans y vacuum. Se controla con el parámetro io_method, que acepta tres valores:
worker: I/O asincrónico vía procesos de fondo. Es el valor por defecto y funciona en cualquier plataforma.io_uring: usa la interfazio_uringdel kernel de Linux, disponible en kernels que la soporten. Es la opción de mayor rendimiento cuando tu sistema la habilita.sync: I/O sincrónico clásico, para replicar el comportamiento previo a PG18 si necesitás descartarlo como variable.
No es una bala de plata para toda carga —los workloads dominados por escritura o por CPU no lo notan tanto— pero para escaneos pesados sobre disco es una diferencia real y gratis con solo actualizar.
¿Qué podés hacer con esto hoy?
Concreto y accionable: si corrés PostgreSQL 16 o 17 en un servidor cloud, planificá el salto a 18.6. El upgrade es más seguro que nunca gracias a las estadísticas que persisten, y las tres funciones de arriba empiezan a rendir sin reescribir tu aplicación.
- Probá el upgrade en staging con
pg_upgrade. Verificá que las estadísticas se trasladan y medí el tiempo hasta rendimiento estable comparado con tu experiencia anterior. - Revisá tus índices multicolumna. Buscá índices redundantes que existían solo para cubrir consultas que omitían la columna líder; con skip scan quizás puedas eliminar alguno y ahorrar escritura y espacio.
- Evaluá
uuidv7()para tablas nuevas de alto volumen. Si arrastrás fragmentación por UUID v4 como PK, medí el impacto en una tabla piloto antes de generalizar. - Ajustá
io_methodsegún tu kernel. Si estás en un Linux conio_uring, probalo contraworkercon tus consultas reales de lectura pesada.
Si operás bases más grandes o con particiones, se combina bien con lo que ya cubrimos en "Particionar tablas grandes por fecha en PostgreSQL" y "Aprende a usar Autovacuum": skip scan y AIO cambian cómo el planner recorre esas particiones.
Preguntas frecuentes sobre PostgreSQL 18
¿Cuándo salió PostgreSQL 18?
PostgreSQL 18 se lanzó el 25 de septiembre de 2025, según el anuncio oficial del PostgreSQL Global Development Group. La rama estable ya va por la minor 18.6, publicada el 13 de agosto de 2026.
¿Cuál es la versión estable de PostgreSQL recomendada hoy?
PostgreSQL 18.6 es la minor estable más reciente de la serie 18 al momento de escribir esta nota. PostgreSQL 19 todavía está en beta (Beta 3, del 13 de agosto de 2026), así que para producción la recomendación es la rama 18.
¿Necesito reescribir mi aplicación para aprovechar el skip scan?
No. El skip scan lo aplica el planificador automáticamente cuando detecta que conviene; no cambiás una línea de SQL ni de código de aplicación. Sí conviene revisar tus índices para eliminar los que se vuelven redundantes.
¿El upgrade a PostgreSQL 18 conserva las estadísticas del optimizador?
Sí. PostgreSQL 18 es la primera versión que mantiene las estadísticas del planificador a través de un upgrade mayor con pg_upgrade, lo que reduce la degradación de rendimiento inmediatamente después de migrar. Antes esas estadísticas se perdían y había que reconstruirlas con ANALYZE.
¿Conviene usar uuidv7() en lugar de uuidv4() como clave primaria?
Para tablas con muchas inserciones, sí: uuidv7() genera identificadores ordenados por tiempo que reducen la fragmentación del índice B-tree que provoca uuidv4(). La contra es que un UUID v7 revela aproximadamente la fecha de creación del registro, algo a considerar si el ID es público y esa información es sensible.
Fuentes: Anuncio oficial de PostgreSQL 18, notas de la versión 18.0, análisis del skip scan (pgEdge) y anuncio de PostgreSQL 18.6 y 19 Beta 3.