PostgreSQL vs MongoDB vs Redis: Comparativa y Arquitectura Técnica
Cualquier equipo de ingeniería se enfrenta tarde o temprano a la decisión crítica de elegir base de datos: ¿conviene estandarizar sobre un motor relacional consolidado, adoptar un almacén de documentos flexible o integrar una caché de estructuras de datos en memoria ultrarrápida?
El debate habitual suele reducirse a una simplificación excesiva: “Tablas vs JSON vs Clave-Valor”. Sin embargo, esa visión oculta los fundamentos de ingeniería que determinan el rendimiento real en producción: motores de almacenamiento, jerarquía de memoria, patrones de E/S en disco, primitivas de concurrencia y mecanismos de registro previo a la escritura (WAL).
En sistemas de alta concurrencia, una elección equivocada desemboca en costes disparados de infraestructura, fragmentación de memoria, bloqueos distribuidos o corrupción silenciosa de datos. Esta guía desglosa la arquitectura interna de PostgreSQL, MongoDB y Redis, comparando sus modelos de ejecución y definiendo un patrón sólido de persistencia políglota.
1. Modelos Mentales de Arquitectura
Antes de comparar sintaxis o métricas, es fundamental entender el propósito operativo y el diseño mecánico de cada tecnología:
| Métrica | PostgreSQL | MongoDB | Redis |
|---|---|---|---|
| Paradigma Principal | Relacional y Objeto-Relacional (RDBMS) | Almacén de Documentos (NoSQL Distribuido) | Almacén de Estructuras en Memoria |
| Unidad de Datos | Tuplas organizadas en páginas de 8KB | Documentos BSON dentro de Colecciones | Claves en memoria asociadas a tipos de datos |
| Motor de Almacenamiento | Heap + Buffer Pool + WAL | WiredTiger (Árbol B + Registro Journal) | En Memoria (RAM) + RDB / AOF opcional |
| Modelo de Concurrencia | Control de Concurrencia Multiversión (MVCC) | Concurrencia a nivel de documento + MVCC | Bucle de eventos monohilo (Patrón Reactor) |
| Perfil de Latencia Típico | 1ms – 15ms (Disco / Shared Buffers) | 1ms – 8ms (Caché WiredTiger / NVMe) | 100µs – 800µs (Acceso directo a DRAM) |
| Garantía de Durabilidad | ACID estricto (Descarga síncrona de WAL) | ACID configurable (Journaling + Write Concern) | Configurable (fsync en AOF / Copias RDB) |
2. Motores de Almacenamiento y Jerarquía de Memoria
La forma en que un motor gestiona la memoria y persiste bytes en disco establece su límite de rendimiento y su comportamiento ante fallos de energía.
PostgreSQL: Páginas Ranuradas, Buffers Compartidos y el Heap
PostgreSQL almacena los datos de las tablas en disco en páginas fijas de 8KB (slotted pages):
- Buffers Compartidos (
shared_buffers): PostgreSQL evita delegar directamente en las operaciones de escritura del sistema operativo gestionando su propia caché de páginas en memoria. Las lecturas verifican primeroshared_buffers; si la página no está presente, el kernel la carga en la caché del SO y posteriormente en la memoria de PostgreSQL. - Write-Ahead Logging (WAL): Al confirmar una transacción (
COMMIT), PostgreSQL escribe las modificaciones secuencialmente en el búfer de WAL y las sincroniza en disco antes de alterar las páginas modificadas en el heap. Esto garantiza recuperación tras caídas del servidor y permite la replicación física continua. - MVCC y Gestión del Bloat: PostgreSQL implementa MVCC generando una nueva versión de la fila (
tuple) en cada actualización o eliminación, etiquetándola conxmin(ID de transacción de creación) yxmax(ID de expiración). Como las tuplas inactivas ocupan espacio en las páginas de 8KB, los procesos en segundo planoVACUUMy autovacuum deben reclamar espacio y congelar IDs para evitar el desbordamiento de transacciones (wraparound). - Tipos de Índices: Soporta indexación avanzada: B-Tree (por defecto para rangos e igualdades), GIN (Índice Invertido Generalizado, esencial para consultar claves anidadas en columnas
JSONB), GiST (para geometrías y búsqueda de texto completo) y BRIN (Block Range Index, óptimo para series temporales masivas secuenciales).
MongoDB: WiredTiger, BSON y Caché Comprimida
MongoDB utiliza el motor de almacenamiento WiredTiger, sustituyendo la arquitectura mmapv1 de versiones anteriores:
- Asignación de Memoria: Por defecto, WiredTiger reserva el
50% de (RAM - 1GB)para su caché interna. El resto de la memoria RAM queda libre para que la caché del sistema operativo retenga bloques comprimidos de disco. - Caché y Compresión en WiredTiger: Los datos en disco se comprimen utilizando Snappy (optimizado para consumo de CPU) o zlib (máxima densidad de compresión). WiredTiger descomprime los bloques en memoria formando estructuras BSON no comprimidas.
- Checkpoints y Journaling: WiredTiger vuelca instantáneas de memoria a disco cada 60 segundos (checkpoints). Para asegurar la durabilidad entre puntos de control, los cambios se escriben en un registro secuencial journal (volcado por defecto cada 100ms o inmediatamente con
w: "majority"yj: true). - Límites del Modelo de Documentos: Los registros se serializan en BSON (JSON binario), que incluye soporte nativo para enteros de 64 bits, decimales IEEE y tipos
ObjectId. Cada documento tiene un límite estricto de 16MB para evitar bloqueos y consumo desmedido de memoria al leer entidades grandes.
Redis: Reactor Monohilo, jemalloc y Registros Persistentes
Redis descarta la dependencia del disco para la ruta de acceso principal: los datos residen en memoria RAM, eliminando las demoras de lectura en disco.
- Ejecución Monohilo: Redis atiende las solicitudes mediante un bucle de eventos monohilo basado en multiplexación de E/S (
epollen Linux,kqueueen macOS/BSD). Al procesar cada comando de manera estrictamente secuencial, elimina cambios de contexto y bloqueos entre hilos, logrando latencias submilisegundo deterministas. Aunque Redis 6.0 introdujo hilos auxiliares para la E/S de sockets de red, la ejecución de comandos permanece monohilo. - Gestión de Memoria: Utiliza
jemallocpara reducir la fragmentación. Al alcanzar el límitemaxmemory, aplica políticas de desalojo comovolatile-lru,allkeys-lru,volatile-lfuoallkeys-lfu. - Mecanismos de Persistencia:
- RDB (Redis Database): Capturas binarias puntuales mediante
bgsave. Redis crea un proceso hijo con Copy-on-Write (COW) del sistema operativo, guardando la imagen de la memoria en un archivo.rdbsin bloquear peticiones entrantes. - AOF (Append-Only File): Registra cada instrucción de modificación. La frecuencia de sincronización en disco se ajusta mediante:
appendfsync always(máxima durabilidad),appendfsync everysec(estándar recomendado en producción: pérdida máxima de 1 segundo de datos) oappendfsync no.
- RDB (Redis Database): Capturas binarias puntuales mediante
3. Modelado de Datos y Ergonomía de Consultas
Comparemos cómo cada sistema representa una entidad del mundo real: un Pedido con cliente, estado y líneas de detalle de productos.
PostgreSQL: Normalización Relacional y JSONB Híbrido
PostgreSQL permite combinar integridad relacional estricta con campos semiestructurados:
-- Modelo Relacional Normalizado
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
customer_id BIGINT NOT NULL REFERENCES customers(id),
status VARCHAR(32) NOT NULL DEFAULT 'pending',
total_amount NUMERIC(12, 2) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE order_items (
id BIGSERIAL PRIMARY KEY,
order_id BIGINT NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
sku VARCHAR(64) NOT NULL,
quantity INTEGER NOT NULL CHECK (quantity > 0),
unit_price NUMERIC(10, 2) NOT NULL
);
-- Enfoque Híbrido Semiestructurado con JSONB e Índice GIN
CREATE TABLE order_events (
id BIGSERIAL PRIMARY KEY,
payload JSONB NOT NULL,
recorded_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_order_events_payload ON order_events USING GIN (payload jsonb_path_ops);
-- Consulta dentro de JSONB con operador de contención (@>)
SELECT id, payload->>'customer_id' AS customer
FROM order_events
WHERE payload @> '{"status": "paid", "currency": "USD"}';
Conclusión clave: PostgreSQL garantiza integridad referencial, borrado en cascada y precisión aritmética con NUMERIC. Si surge necesidad de flexibilidad, JSONB aporta capacidades de documento con índices especializados sin perder las garantías ACID.
MongoDB: Documentos Embebidos y Pipeline de Agregación
En MongoDB, los elementos del pedido se integran directamente dentro del documento raíz, evitando la necesidad de unir tablas (joins):
// Inserción de un documento anidado en MongoDB
db.orders.insertOne({
customerId: ObjectId("66e1f0c29a1b2c3d4e5f6789"),
status: "paid",
totalAmount: 149.50,
items: [
{ sku: "TECLADO-MEC-01", qty: 1, price: 109.50 },
{ sku: "CABLE-USB-C-2M", qty: 2, price: 20.00 }
],
metadata: { fuente: "app_movil", canal: "organico" },
createdAt: new Date()
});
// Consulta analítica mediante Pipeline de Agregación ($match, $unwind, $group)
db.orders.aggregate([
{ $match: { status: "paid" } },
{ $unwind: "$items" },
{ $group: {
_id: "$items.sku",
totalQuantitySold: { $sum: "$items.qty" },
revenue: { $sum: { $multiply: ["$items.qty", "$items.price"] } }
}},
{ $sort: { revenue: -1 } },
{ $limit: 10 }
]);
Conclusión clave: Los documentos embebidos agilizan lecturas de entidades completas. Sin embargo, transformaciones complejas entre colecciones requieren agregaciones avanzadas, y la validación de esquemas se traslada a la aplicación o a reglas $jsonSchema.
Redis: Estructuras Primitivas y Clave-Valor
Redis no ofrece tablas ni colecciones arbitrarias; el modelo de datos se construye combinando estructuras nativas:
# Almacenar pedido en un Hash para lectura inmediata de campos
HSET order:1001 customer_id "98234" status "paid" total_amount "149.50"
# Leer el estado en microsegundos
HGET order:1001 status
# Añadir a la cronología del cliente mediante un Sorted Set ordenado por timestamp
ZADD customer:98234:orders 1760342400 "order:1001"
# Obtener los 10 pedidos más recientes del cliente
ZREVRANGE customer:98234:orders 0 9
# Decremento atómico del inventario sin condiciones de carrera (O(1))
DECRBY inventory:TECLADO-MEC-01 1
Conclusión clave: Redis exige que el desarrollador diseñe los índices secundarios mediante conjuntos ordenados (ZSET), conjuntos (SET) y hashes (HSET). Sobresale en accesos atómicos y directos a memoria.
4. ACID, Transacciones y el Teorema CAP
La diferencia crítica entre estos motores reside en cómo gestionan las particiones de red, los conflictos de concurrencia y los niveles de aislamiento.
Consistencia (C)
/\
/ \
/ \
/ CA \
/ \
PostgreSQL --/----------\-- MongoDB (Por defecto CP)
/ \
/ \
/________________\
Disponibilidad (A) AP Tolerancia a Particiones (P)
\ /
\-- Redis ---/ (Sesgo AP en Replicación/Cluster)
PostgreSQL: Garantías ACID y Niveles de Aislamiento ANSI
PostgreSQL ofrece garantías transaccionales sólidas entre múltiples tablas:
- Niveles de aislamiento soportados: Read Committed (predeterminado), Repeatable Read y Serializable.
- Aislamiento Serializable Snapshot (SSI): Detecta anomalías de lectura y escritura (write skew) sin recurrir a bloqueos masivos de tablas, abortando únicamente aquellas transacciones que violen la serialización.
- Integridad en nodo principal: Dentro de la instancia primaria, la consistencia es absoluta. Al escalar lecturas mediante réplicas físicas, éstas operan con consistencia eventual salvo que se active la replicación síncrona (
synchronous_commit = on).
MongoDB: Atomicidad en Documento y Transacciones Distribuidas 2PC
- Atomicidad por Documento: Las modificaciones sobre un documento individual son siempre atómicas, incluso en matrices y campos anidados.
- Transacciones Multidocumento: Incorporadas en MongoDB 4.0 (conjuntos de réplicas) y 4.2 (clústeres fragmentados o sharded), implementan aislamiento de instantánea (snapshot isolation) coordinado mediante el protocolo de confirmación en dos fases (Two-Phase Commit, 2PC).
- Consistencia Ajustable: Los desarrolladores pueden calibrar el intercambio CAP:
writeConcern: { w: "majority", j: true, wtimeout: 5000 }confirma que la escritura se ha registrado en el quórum de réplicas antes de responder al cliente.readConcern: "linearizable"garantiza lecturas consistentes con el quórum mayoritario, evitando lecturas obsoletas en caso de particiones de red.
Redis: Atomicidad por Bucle de Eventos y Bloqueo Optimista
- Atomicidad por Comando: Dado que la ejecución es monohilo, instrucciones como
INCR,HSETyLPUSHse ejecutan atómicamente sin necesidad de bloqueos manuales. - Bloques
MULTI/EXEC: Agrupan instrucciones en una cola que se ejecuta sin interferencia de otros clientes. Nota importante: Redis no realiza rollback automático si una instrucción falla por tipo de datos erróneo; el resto de operaciones del bloque continúa su ejecución. - Bloqueo Optimista con
WATCH: Permite operaciones seguras de tipo Check-And-Set (CAS):WATCH balance:cuenta_a # Comprobar saldo en la aplicación... MULTI DECRBY balance:cuenta_a 50 INCRBY balance:cuenta_b 50 EXEC # Devuelve nil si balance:cuenta_a fue modificado por otro cliente en el intervalo - Scripts Lua y Redis Functions: Permiten ejecutar lógica transaccional compleja en el servidor con garantía de ejecución atómica mediante
EVALo Redis Functions.
5. Latencia, Rendimiento y Topologías de Escalado
El rendimiento está supeditado a los límites del hardware: caché de CPU, ancho de banda de DRAM, IOPS de unidades NVMe y latencia de red.
Comparativa de Latencias en Carga
Redis (DRAM) : [0.1ms - 0.8ms] 🚀
MongoDB (WiredTiger): [1.0ms - 5.0ms] ⚡
PostgreSQL (NVMe) : [1.5ms - 12.0ms] 🛡️
- Redis: La latencia se mide en microsegundos. La búsqueda en memoria concluye en nanosegundos, quedando limitada únicamente por la pila de red TCP (0.2ms – 0.8ms). Una sola instancia procesa fácilmente entre 100.000 y 500.000 operaciones por segundo por núcleo.
- MongoDB: Las lecturas indexadas sobre datos calientes en caché se completan en 1ms – 5ms. La capacidad de escritura escala horizontalmente dividiendo datos entre shards.
- PostgreSQL: Las búsquedas puntuales sobre índices B-Tree en
shared_bufferstardan 1ms – 4ms. Consultas complejas con uniones de varias tablas y funciones de ventana requieren 10ms – 100ms+, lo que refleja el coste de CPU al comparar filas y ordenar resultados.
Estrategias de Escalado
- PostgreSQL:
- Escalado vertical: Aumento de CPU y memoria del nodo principal.
- Escalado de lecturas: Réplicas físicas mediante streaming replication.
- Gestión de conexiones: Es imprescindible emplear agrupadores como PgBouncer u Odyssey para mitigar la sobrecarga del modelo de procesos de PostgreSQL.
- Particionado horizontal: Requiere extensiones especializadas como Citus o particionado a nivel de aplicación.
- MongoDB:
- Sharding nativo: Diseñado para escalar horizontalmente de forma nativa mediante enrutadores
mongos, servidores de configuración (config servers) y conjuntos de réplicas de datos (shards).
- Sharding nativo: Diseñado para escalar horizontalmente de forma nativa mediante enrutadores
- Redis:
- Redis Cluster: Divide el espacio de claves de forma automática entre 16.384 ranuras hash (hash slots).
- Coste de memoria: Limitado por el precio de la memoria RAM. Mantener 10TB de datos en memoria RAM de Redis es entre 15 y 30 veces más costoso que almacenar 10TB en unidades NVMe con PostgreSQL o MongoDB.
6. Matriz de Decisión para Arquitectos
Utiliza esta matriz para seleccionar el motor adecuado según el tipo de carga de trabajo:
| Requisito / Escenario | Motor Recomendado | Justificación Técnica Principal |
|---|---|---|
| Contabilidad, Pagos y Facturación | PostgreSQL | Cumplimiento ACID estricto, claves foráneas, tipos numéricos exactos y cero pérdida de datos. |
| Autenticación y Núcleo Relacional | PostgreSQL | Grafos de permisos complejos, integridad de entidades y cumplimiento normativo. |
| Catálogos Dinámicos de E-Commerce | MongoDB | Atributos polimórficos cambiantes en millones de artículos sin migraciones DDL constantes. |
| Gestión de Sesiones y Listas Negras de Tokens | Redis | Búsqueda en microsegundos, expiración nativa por TTL y ausencia de cuellos de botella en disco. |
| Limitadores de Tasa Distribuidos (Rate Limiting) | Redis | Primitivas atómicas INCR y EXPIRE o scripts Lua de alto rendimiento en pasarelas de API. |
| Clasificaciones en Tiempo Real (Leaderboards) | Redis | Estructuras Sorted Sets (ZADD, ZRANK) que resuelven ordenamientos con complejidad $O(\log N)$. |
| Ingesta de Telemetría IoT (100k escrituras/seg) | MongoDB / Redis | Redis como búfer de absorción o colecciones temporales (time-series) de MongoDB con empaquetado automático. |
| Informes Analíticos Complejos y Consultas Ad-hoc | PostgreSQL | Optimizador SQL maduro, funciones de ventana (ROW_NUMBER(), RANK()), CTEs y ejecución paralela. |
7. Arquitectura en Producción: Persistencia Políglota en 3 Capas
Las arquitecturas de alto tráfico rara vez eligen una única base de datos. Integran PostgreSQL, MongoDB y Redis en un patrón coordinado de Persistencia Políglota:
Petición del Cliente
│
▼
┌───────────────────┐
│ API Gateway / LB │
└─────────┬─────────┘
│
1. Rate Limit y Sesión de Usuario
│
▼
┌─────────────────┐
│ Caché Redis │
│ (Tokens / TTL) │
└────────┬────────┘
│
▼
┌───────────────────┐
│ Backend Principal │
└────┬────────────┬─┘
│ │
2. Transacciones / │ │ 3. Catálogo Polimórfico /
Datos Principales │ │ Eventos y Logs
▼ ▼
┌────────────┐ ┌────────────┐
│ PostgreSQL │ │ MongoDB │
│ (SSOT) │ │ (Catálogo) │
└────────────┘ └────────────┘
Funciones en la Arquitectura de Producción:
- Redis (Capa de Aceleración y Límite):
- Aplica limitación de peticiones mediante algoritmos de cubo de fichas (token bucket).
- Administra sesiones de usuario, revocación de JWT y presencia en WebSockets.
- Funciona como capa Cache-Aside para resultados de consultas pesadas de PostgreSQL (con TTLs y desalojo por eventos).
- PostgreSQL (Fuente Única de la Verdad - SSOT):
- Custodia usuarios, entidades comerciales, suscripciones, pedidos y libros contables.
- Aplica integridad referencial estricta para evitar inconsistencias en pagos o clientes.
- Utiliza
JSONBpara almacenar payloads variables de webhooks de terceros.
- MongoDB (Capa de Documentos Especializada):
- Gestiona catálogos de productos donde distintas categorías requieren atributos totalmente diferentes.
- Ingesta registros de auditoría o eventos de navegación donde el particionado horizontal nativo es prioritario desde el primer día.
Conclusiones y Próximos Pasos
No existe una base de datos universal.
- Establece PostgreSQL como tu motor relacional predeterminado. Su robustez ACID, extensiones (PgBouncer, PostGIS, pgvector) y soporte nativo para
JSONBresuelven la gran mayoría de casos de uso empresariales sin añadir complejidad operativa innecesaria. - Incorpora Redis junto a PostgreSQL cuando requieras respuestas en microsegundos, limitación atómica de tráfico o gestión de sesiones en memoria.
- Adopta MongoDB cuando el modelo de negocio demande estructuras de documentos dinámicas o cuando el volumen de escritura exija escalabilidad horizontal distribuida de forma nativa.
El dominio del diseño de esquemas, las relaciones y la optimización de consultas sigue siendo la base de todo ingeniero de datos.
👉 Aprende arquitectura de bases de datos de forma interactiva en SQLMaster. Modela tablas, define claves foráneas y practica consultas complejas en tu navegador.
Prueba los ejemplos en SQL Lab
Copia la preparación y las consultas de esta guía en el laboratorio. Los ejemplos usan SQLite. Las lecciones y las instrucciones del laboratorio están en inglés.
Abrir SQL Lab