⏱️ Lectura: 15 min

La mayoría de los proyectos que prometen ‘reescribir X en Rust’ nunca pasan de una demo bonita en GitHub. pgrust rompe el patrón. Al intentar reescribir PostgreSQL en Rust, su autor sometió el código a tanto testing que terminó encontrando bugs reales dentro del Postgres original, el que corre en producción en todo el mundo.

📑 En este artículo
  1. TL;DR
  2. ¿Qué es pgrust?
  3. Por qué reescribir PostgreSQL en Rust es una apuesta real
  4. Cómo pgrust destapó bugs reales en Postgres
  5. Ejemplos prácticos: cómo se ve el testing diferencial
  6. Casos de uso reales
  7. Comparativa: pgrust y otros intentos de reinventar Postgres
  8. Errores comunes al intentar una reescritura como pgrust
  9. Profundizando: por qué una segunda implementación destapa bugs en la primera
  10. Preguntas frecuentes
    1. ¿pgrust ya está listo para reemplazar a PostgreSQL en producción?
    2. ¿Quién desarrolla pgrust?
    3. ¿Qué bugs encontró pgrust en Postgres?
    4. ¿Por qué alguien reescribiría PostgreSQL en Rust en lugar de parchear el original?
    5. ¿La reimplementación de PostgreSQL en Rust mejora la seguridad de memoria?
    6. ¿Qué pasa si pgrust nunca termina de ser un reemplazo completo de Postgres?
  11. Referencias
    1. 📚 Artículos relacionados

Esto no es otro meme de ‘rewrite it in Rust’. Es la prueba de que, si el testing es agresivo y honesto, hasta un proyecto personal sin terminar puede mejorar al software que imita. Acá va qué es pgrust, qué errores destapó en Postgres y qué significa como caso de reescritura segura de software maduro.

TL;DR

  • pgrust es un proyecto personal de Michael Malis que busca reescribir PostgreSQL en Rust, enfocado en rendimiento.
  • Su testing agresivo ya halló cinco bugs reales en Postgres, incluidos fallos en SP-GiST y JSONPath.
  • Las optimizaciones de pgrust podrían llegar a Postgres o ClickHouse aunque el rewrite nunca llegue a producción.
  • Dan Luu documentó los bugs en danluu.com/ambitious como ejemplo de testing riguroso, sin relleno de IA.
  • La mayoría de los rewrites virales de hoy son humo generado con IA: pgrust se distingue por probar en serio.

¿Qué es pgrust?

pgrust es un proyecto personal del ingeniero Michael Malis que busca reescribir PostgreSQL en Rust manteniendo compatibilidad de protocolo y de disco con el Postgres original escrito en C. No es un fork cosmético: reimplementa el motor de almacenamiento, el planificador de consultas y buena parte de los tipos de datos nativos.

El objetivo declarado no es la pureza arquitectónica, sino el rendimiento. Según relata Dan Luu, la apuesta de Malis es que un motor escrito en Rust, con mejor control de memoria y menos indirección que el C clásico de Postgres, puede ejecutar las mismas consultas más rápido sin sacrificar compatibilidad con el ecosistema de clientes, drivers y extensiones que ya existe para PostgreSQL.

Pero lo que hace relevante a pgrust no es la promesa de velocidad, todavía sin datos públicos comparables. Es el nivel de testing que Malis aplicó mientras construía el reemplazo, tan exhaustivo que el propio proceso de validar que pgrust se comportaba igual que Postgres terminó revelando errores que llevaban tiempo escondidos en el código original.

PostgreSQL nació en los años noventa y su núcleo sigue escrito en C. Foto de Thomas Tastet en Unsplash

Por qué reescribir PostgreSQL en Rust es una apuesta real

En Hacker News y Reddit aparece un ‘rewrite it in Rust’ nuevo casi cada semana. La mayoría son demos de un fin de semana: implementan el 5% más fácil de un programa complejo, publican un benchmark favorable y desaparecen. Por eso la reacción automática ante un anuncio así es la desconfianza, y en 2026 esa desconfianza está más justificada que nunca. Sobra código generado por IA sin pruebas reales detrás.

El caso de pgrust es distinto porque Malis no se detuvo en el ‘hola mundo’ del motor. Para asegurarse de que su reescritura devuelve exactamente los mismos resultados que Postgres, construyó un proceso de verificación que corre las mismas consultas contra ambos motores y compara las salidas. Esa disciplina, conocida en ingeniería de software como testing diferencial, es costosa de hacer bien, y es la razón por la que la mayoría de los rewrites nunca llega a ese nivel.

💭 Clave: el testing diferencial no solo valida el código nuevo, también expone bugs latentes en el código viejo, porque obliga a definir sin ambigüedad cuál es el comportamiento correcto para cada caso límite.

Cómo pgrust destapó bugs reales en Postgres

Mientras Malis construía la reimplementación de PostgreSQL, el proceso de comparar resultado contra resultado fue encontrando discrepancias. Cada discrepancia era una de dos cosas: un bug en pgrust, o un bug que ya existía en el Postgres original y que nadie había detectado. Según el recuento de Dan Luu, al menos cinco de esas discrepancias resultaron ser fallos reales en el propio Postgres.

flowchart TD
A["Misma consulta SQL"] --> B["Postgres original en C"]
A --> C["pgrust en Rust"]
B --> D["Resultado A"]
C --> E["Resultado B"]
D --> F["Comparador byte a byte"]
E --> F
F --> G["Diferencia encontrada"]
G --> H["Bug reportado a Postgres"]
Subsistema afectado Tipo de bug Por qué importa
SP-GiST Error numérico Podía hacer fallar operaciones válidas sobre este método de indexación
JSONPath Caché de formato corrupta Devolvía resultados incorrectos en consultas jsonb con rutas JSONPath
pgcrypto Estado inconsistente Una operación de cifrado podía dejar al módulo en un estado que rompía llamadas posteriores
Cargador de diccionarios de búsqueda de texto Varios bugs de memoria Podía corromper memoria al cargar diccionarios de búsqueda de texto completo (ispell, sinónimos)
Tipo money Overflow numérico El tipo monetario podía desbordarse fuera de su rango documentado

Ninguno de estos bugs es exótico. Todos afectan funciones que cualquier aplicación en producción puede estar usando hoy sin saberlo. Encontrar un fallo en SP-GiST importa porque ese método de indexación respalda tipos de búsqueda espacial y de rango, y romper JSONPath importa porque jsonb es, desde Postgres 12, la forma estándar de guardar documentos semiestructurados dentro de una base relacional.

pgrust tampoco está libre de errores, y Malis lo deja claro: el propio proyecto sigue en desarrollo. Pero ese no es el punto. Incluso si pgrust nunca reemplaza a Postgres en producción, el proceso de intentarlo ya dejó una mejora durable en el software que todos usan, porque los bugs reportados se corrigen en el Postgres real, no en una copia paralela que nadie corre.

Ejemplos prácticos: cómo se ve el testing diferencial

No hace falta tener el código de pgrust para entender la técnica. El testing diferencial compara, consulta por consulta, lo que devuelven dos implementaciones que deberían comportarse igual. Un ejemplo simplificado en Python usando psycopg2, comparando dos conexiones cualesquiera que hablen el protocolo de PostgreSQL:

import psycopg2

def run(dsn, query):
    with psycopg2.connect(dsn) as conn:
        with conn.cursor() as cur:
            cur.execute(query)
            return cur.fetchall()

query = "SELECT '1234567.89'::money, upper('hola');"

resultado_a = run("dbname=postgres_original", query)
resultado_b = run("dbname=postgres_candidato", query)

if resultado_a != resultado_b:
    print(f"DIVERGENCIA en: {query}")
    print(f"  original:  {resultado_a}")
    print(f"  candidato: {resultado_b}")
else:
    print("Resultados iguales")

Al correr este script contra dos instancias idénticas de Postgres, la salida esperada es Resultados iguales. La técnica se vuelve interesante cuando una de las dos conexiones apunta a una reescritura como pgrust: ahí, cualquier DIVERGENCIA impresa es una pista de un bug, ya sea en la reescritura o, como pasó varias veces con pgrust, en el propio Postgres.

sequenceDiagram
participant Cliente
participant Postgres as "Postgres original"
participant Pgrust as "pgrust"
Cliente->>Postgres: ejecuta consulta SQL
Cliente->>Pgrust: ejecuta la misma consulta
Postgres-->>Cliente: devuelve resultado A
Pgrust-->>Cliente: devuelve resultado B
Note over Cliente: compara A y B byte a byte

Para confirmar que una divergencia es real y no un artefacto de la conexión, conviene repetir la consulta con EXPLAIN (ANALYZE, BUFFERS) en ambas conexiones. Si los planes de ejecución son distintos, la causa puede estar en la configuración y no en un bug del motor. Escalar esta técnica suele implicar generar consultas aleatorias con un fuzzer y dejarlo correr durante horas, acumulando casos límite que ningún test escrito a mano cubriría.

Casos de uso reales

La idea detrás del port a Rust de Postgres no nació con pgrust. Rust ya tiene un historial de reemplazar herramientas Unix clásicas: ripgrep sustituyó a grep en el día a día de muchos desarrolladores, y el proyecto uutils reescribe las herramientas GNU coreutils completas en Rust. En bases de datos, Neon separó el almacenamiento de Postgres en una capa propia escrita en Rust para habilitar bifurcaciones instantáneas de bases de datos, y OrioleDB reescribió el motor de almacenamiento de Postgres como extensión, aunque se mantuvo en C.

Lo que comparten estos proyectos con pgrust es que ninguno promete reemplazar de un día para el otro al original. Compiten en un subconjunto del problema, bajo cargas reales, y dejan que el tiempo, y el testing, decidan si la reescritura sostiene la comparación.

Comparativa: pgrust y otros intentos de reinventar Postgres

La tabla compara el alcance de pgrust con otros proyectos conocidos en el mismo espacio:

Proyecto Qué reescribe Lenguaje Objetivo principal
pgrust El motor completo de PostgreSQL Rust Rendimiento con compatibilidad de protocolo
OrioleDB El motor de almacenamiento, como extensión C Mejor manejo de MVCC y menos bloat
Neon La capa de almacenamiento, separada del cómputo Rust Bases de datos serverless con branching
uutils coreutils Las herramientas GNU coreutils Rust Reemplazo memory-safe de utilidades Unix
La programación N-version se usa desde los años setenta en sistemas donde un bug no se puede tolerar, como el control de vuelo. Foto de Kenny Van Roosbroek en Unsplash

Errores comunes al intentar una reescritura como pgrust

El error más común es declarar éxito con un microbenchmark. Correr una sola consulta simple más rápido que el original no prueba nada sobre un motor de base de datos. Lo que importa es el comportamiento bajo cargas mixtas, con índices, transacciones concurrentes y datos reales. pgrust evita este error apoyándose en comparar resultados, no solo tiempos.

Otro error es subestimar la superficie de compatibilidad. Postgres no es solo el motor SQL: es también el protocolo de red que hablan psql y cada driver, el formato binario de los tipos de datos, y decenas de extensiones de terceros. Una reescritura que ignora alguno de esos contratos rompe aplicaciones silenciosamente, mucho después de publicada.

El tercer error, menos técnico, es juzgar cada intento de rewrite por el promedio de la categoría. La mayoría de los proyectos ‘reescribí X en Rust’ que circulan hoy son, en efecto, poco más que demos generadas con asistencia de IA sin testing real detrás. Pero descartar a pgrust solo por pertenecer a esa categoría ignora la evidencia concreta de los cinco bugs reportados y corregidos en Postgres.

⚠️ Ojo: que una reescritura encuentre bugs en el original no prueba que la reescritura misma esté lista para producción. pgrust sigue siendo un proyecto personal en desarrollo, no un reemplazo certificado de Postgres.

Profundizando: por qué una segunda implementación destapa bugs en la primera

El fenómeno detrás de pgrust tiene nombre en ingeniería de software: programación N-version, una técnica de los años setenta que consiste en construir varias implementaciones independientes de la misma especificación y compararlas en busca de divergencias. La lógica es simple. Es poco probable que dos implementaciones distintas cometan exactamente el mismo error en el mismo caso límite, así que cualquier diferencia es sospechosa.

Rust aporta algo que las implementaciones alternativas en C no tienen gratis. Su verificador de préstamos (borrow checker) impide, en tiempo de compilación, clases enteras de errores de memoria como use-after-free o buffer overflows. Eso no elimina los bugs lógicos, como el overflow del tipo money, que es un error de rango y no de memoria, pero sí reduce la clase de bugs que pgrust puede introducir mientras reconstruye la lógica de Postgres.

fn main() {
    let datos = vec![1, 2, 3];
    let referencia = &datos[0];
    datos.push(4);
    println!("{}", referencia);
}

Este programa no compila en Rust. El compilador rechaza el push porque mantiene viva una referencia a datos. La salida real al compilarlo con rustc es un error del tipo cannot borrow `datos` as mutable because it is also borrowed as immutable, detectado antes de ejecutar una sola línea. En C, el equivalente compilaría sin avisos y fallaría, o no, recién en tiempo de ejecución.

Hay un matiz importante. Encontrar un bug con testing diferencial es más fácil que arreglarlo bien. Cada fallo reportado a Postgres pasa por su propio proceso de revisión, con su propia discusión sobre si el comportamiento documentado coincide con lo que el código realmente hace. Varias de las correcciones de los bugs que destapó pgrust requirieron esa discusión antes de aceptarse, porque el problema no era solo que el código estuviera mal, sino decidir qué dice la documentación que debería pasar en ese caso.

Hay un contexto más amplio detrás de este caso, que Dan Luu plantea en el mismo artículo: las herramientas actuales, incluida la asistencia de IA para programar, bajaron tanto el costo de intentar proyectos ambiciosos que antes tomaban años, que hoy un desarrollador puede llegar a una versión funcional en horas. Pero esa misma facilidad multiplicó la cantidad de proyectos de baja calidad que se presentan como reescrituras serias. Lo que distingue a pgrust del resto es el testing agresivo detrás. Esa disciplina fue la que terminó encontrándole grietas al propio Postgres.

Tu próximo paso: tomá cualquier extensión chica de PostgreSQL en C que tengas instalada, levantá dos bases con la misma versión, corré la misma batería de consultas contra ambas con un script como el de arriba y comparón los resultados byte a byte antes de confiar en que un cambio de configuración es inofensivo.

📖 Resumen en Telegram: Ver resumen

📬 Recibí lo nuevo en tu email

Te avisamos de artículos grandes (1-2 por mes).

Preguntas frecuentes

¿pgrust ya está listo para reemplazar a PostgreSQL en producción?

No. Es un proyecto personal en desarrollo, sin la madurez ni el ecosistema de extensiones que tiene Postgres tras casi tres décadas en producción. Su valor hoy está en el proceso de testing, no en ser un reemplazo listo para usar.

¿Quién desarrolla pgrust?

El ingeniero Michael Malis, quien comparte avances del proyecto de forma informal. Dan Luu documentó el trabajo en su blog después de verificar los reportes de bugs que generó.

¿Qué bugs encontró pgrust en Postgres?

Al menos cinco: un error numérico en SP-GiST, una caché de formato corrupta que rompía JSONPath, un estado inconsistente en pgcrypto, varios bugs de memoria en el cargador de diccionarios de búsqueda de texto, y un overflow en el tipo money.

¿Por qué alguien reescribiría PostgreSQL en Rust en lugar de parchear el original?

Porque algunas optimizaciones de rendimiento requieren cambios estructurales profundos en el motor de almacenamiento, difíciles de introducir de forma incremental en una base de código de treinta años sin romper compatibilidad. Reescribir desde cero, con testing diferencial contra el original, permite probar esos cambios sin arriesgar producción.

¿La reimplementación de PostgreSQL en Rust mejora la seguridad de memoria?

En teoría sí, porque Rust elimina en tiempo de compilación clases de bugs de memoria que en C dependen de la disciplina del programador. Pero eso no impide bugs lógicos como el overflow de rango que pgrust encontró en el tipo money, que no es un bug de memoria.

¿Qué pasa si pgrust nunca termina de ser un reemplazo completo de Postgres?

Igual deja valor: cada bug real que destapó ya se corrigió o se está corrigiendo en el Postgres que todos usan, y las optimizaciones de rendimiento que demuestre podrían adaptarse a Postgres o a otros motores como ClickHouse.

Referencias

📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.

Imagen destacada: Foto de CDC en Unsplash

¿Te sirvió? ¿Te dio otro error? Contalo abajo: las preguntas se responden y le sirven al siguiente que llegue.

Dejar un comentario

Andrés Morales

Desarrollador e investigador en inteligencia artificial. Escribe sobre modelos de lenguaje, frameworks, herramientas para devs y lanzamientos open source. Cubre papers de ML, ecosistema de startups tech y tendencias de programación.

0 Comentarios

Deja un comentario

Marcador de posición del avatar

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Podés incluir código entre <code>…</code> o, para varias líneas, <pre><code>…</code></pre>.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.