Menu

SQLite vs PostgreSQL: ¿cuál elegir y cuándo?

Diferencias reales entre SQLite y PostgreSQL: arquitectura, concurrencia, tipos de datos y qué tipo de proyecto encaja mejor con cada uno.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Dos bases de datos, dos enfoques distintos

Tanto SQLite como PostgreSQL hablan SQL, almacenan datos relacionales y pueden mover aplicaciones reales en producción. A partir de ahí, están pensadas para mundos muy diferentes.

  • SQLite es una librería. Vive dentro del proceso de tu aplicación y lee un único archivo .db en disco. Sin servidor, sin puertos, sin usuarios que configurar.
  • PostgreSQL es un servidor. Corre como su propio proceso, escucha en un puerto de red y tu aplicación se conecta a él como cliente.

Casi todas las demás diferencias entre SQLite y PostgreSQL —concurrencia, despliegue, rigor de tipos, rendimiento— nacen de esa decisión de arquitectura. Tenlo presente mientras avanzamos.

Arquitectura: in-process vs cliente/servidor

Abrir una base de datos SQLite es, literalmente, abrir un archivo:

No hay ningún demonio que arrancar, ningún pg_hba.conf que tocar, ningún puerto que exponer. Tu aplicación carga la librería de SQLite, abre notes.db y empieza a lanzar consultas. El despliegue se reduce a "copiar el archivo".

Con PostgreSQL la cosa cambia:

# Inicia el servidor (una vez, como administrador):
sudo systemctl start postgresql

# Luego conéctate desde tu aplicación:
psql -h localhost -U alice -d mydb

Tu aplicación habla con un proceso aparte — normalmente por TCP, a veces por un socket Unix. Esa capa extra te cuesta tiempo de configuración y un round-trip de conexión por cada consulta, pero a cambio ganas acceso por red, autenticación multiusuario y verdaderos escritores concurrentes.

Concurrencia: el factor decisivo

Aquí suele estar la clave a la hora de elegir. SQLite serializa las escrituras: en un momento dado, un único escritor mantiene el bloqueo sobre el fichero de la base de datos, y el resto espera su turno. Las lecturas sí pueden ir en paralelo (sobre todo en modo WAL), pero las escrituras van de una en una.

Postgres usa MVCC (control de concurrencia multiversión) y bloqueo a nivel de fila. Muchas transacciones pueden escribir a la vez en filas distintas sin pisarse unas a otras.

Llevándolo a casos reales:

  • ¿Un blog con 50 lecturas por segundo y un autor que escribe de vez en cuando? SQLite te sobra.
  • ¿Un checkout de e-commerce donde cientos de usuarios actualizan el stock a la vez? Postgres.
  • ¿La caché local de una app móvil? SQLite, sin discusión.
  • ¿Un backend SaaS multi-tenant con decenas de workers en segundo plano? Postgres.

El modo WAL (PRAGMA journal_mode = WAL;) mejora bastante la concurrencia en SQLite — las lecturas dejan de bloquear a las escrituras —, pero no cambia la regla de oro: un solo escritor a la vez.

Sistemas de tipos: laxo frente a estricto

Postgres es estricto. Una columna declarada como INTEGER rechaza cadenas, sin contemplaciones:

-- Postgres
CREATE TABLE t (n INTEGER);
INSERT INTO t (n) VALUES ('not a number');
-- ERROR: sintaxis de entrada no válida para tipo integer

SQLite, por defecto, usa lo que se conoce como type affinity (afinidad de tipos): más que una regla estricta, es una sugerencia. Por eso el mismo INSERT funciona sin problemas:

La cadena se queda ahí tan tranquila, dentro de una columna INTEGER. SQLite la guardó como texto. Esta flexibilidad fue una decisión de diseño consciente: muy útil para prototipos rápidos, pero peligrosa en esquemas que van a durar.

Las versiones modernas de SQLite (3.37+) admiten tablas STRICT, que se comportan más como Postgres:

Si vas a empezar un proyecto nuevo con SQLite, usa STRICT. Te quitas de encima toda una categoría de sorpresas del estilo "¿por qué hay un string en mi columna numérica?".

Funcionalidades disponibles

PostgreSQL tiene más de casi todo: tipos de datos (arrays, rangos, geométricos, de red, enums personalizados), lenguajes procedurales (PL/pgSQL, PL/Python), búsqueda de texto completo con ranking, vistas materializadas, particionado de tablas, replicación, seguridad basada en roles y un ecosistema enorme de extensiones (PostGIS, TimescaleDB, pgvector).

SQLite cubre lo esencial y añade algunas funciones interesantes para su escala: funciones JSON, búsqueda de texto completo con FTS5, índices R-Tree, funciones de ventana, CTEs y columnas generadas. Lo que se deja fuera es todo lo que dé por hecho que hay un servidor: usuarios, roles, replicación, acceso por red.

Un modelo mental rápido:

  • ¿Necesitas GIS, búsqueda vectorial o replicación? PostgreSQL.
  • ¿Necesitas embeber una base de datos dentro de una app de iOS? SQLite.
  • ¿Necesitas las dos? Muchos equipos desarrollan y testean con SQLite y despliegan en PostgreSQL — aunque esa mezcla te puede jugar malas pasadas con las diferencias de sintaxis (lo vemos a continuación).

Diferencias de sintaxis con las que te vas a topar

La mayor parte del SQL del día a día es idéntico. Las diferencias se concentran en el esquema, los tipos y unas cuantas funciones integradas:

-- Clave primaria autoincremental
-- SQLite:
CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);
-- Postgres:
CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT);
-- o, en Postgres moderno:
CREATE TABLE users (id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT);

-- Marca de tiempo actual
-- SQLite:  CURRENT_TIMESTAMP   (devuelve texto)
-- Postgres: NOW()              (devuelve timestamp)

-- Tipo booleano
-- SQLite:  no hay BOOLEAN real; usa INTEGER 0/1
-- Postgres: BOOLEAN con TRUE/FALSE

Si desarrollas con SQLite y despliegas en Postgres, te conviene tener un ORM o una herramienta de migraciones entre tu código y el SQL en crudo. Si no, estas diferencias se te van a colar en la aplicación.

Rendimiento, sin trampas: SQLite vs PostgreSQL

"Más rápido" depende de la pregunta. Si tienes un solo proceso haciendo lecturas y escrituras pequeñas, ganarle a SQLite es complicado: no hay salto por red, ni parseo de protocolo, ni conexión cliente-servidor. En benchmarks con un único cliente, SQLite suele superar a Postgres en consultas sencillas.

Pero mete varios escritores concurrentes, datasets grandes que requieren ejecución paralela de consultas, o planes de ejecución complejos que se benefician del planificador maduro de Postgres, y ahí Postgres toma la delantera. Postgres también escala verticalmente (máquinas más grandes, más núcleos) de un modo para el que SQLite simplemente no está diseñado.

Resumen sin adornos: SQLite es rápido para lo suyo. Postgres es rápido para lo suyo. Elige según la forma de tu carga de trabajo, no según titulares de benchmarks.

Guía rápida: ¿SQLite o PostgreSQL, cuál usar?

Tira de SQLite cuando:

  • Los datos viven junto a una sola aplicación: escritorio, móvil, embebido, herramienta CLI.
  • Las escrituras vienen de un único proceso o de unos pocos.
  • Quieres un despliegue sin configuración.
  • Estás prototipando y prefieres concentrarte en el esquema, no en la infraestructura.

Tira de Postgres cuando:

  • Varios servidores de aplicación o workers escriben en la base de datos.
  • Necesitas acceso por red desde muchos clientes.
  • Necesitas funciones avanzadas: roles, replicación, GIS, tipos personalizados, procedimientos almacenados.
  • Los datos son el almacén central y duradero de un servicio en producción.

Un camino habitual: arrancar un proyecto pequeño con SQLite y migrar a Postgres si —y cuando— el patrón de tráfico lo exija. Migrar de SQLite a PostgreSQL no es gratis, pero es una operación conocida, y la mayoría de proyectos nunca la necesitan.

Lo que viene: cuándo SQLite es la elección correcta

La comparación de arriba te da los trade-offs. La siguiente página profundiza en los argumentos a favor de SQLite: las cargas de trabajo donde no es solo suficientemente bueno, sino realmente la mejor herramienta, y las señales de alarma que indican que se te ha quedado pequeño.

Preguntas frecuentes

¿Cuál es la diferencia principal entre SQLite y PostgreSQL?

SQLite es una librería embebida que lee y escribe sobre un único fichero dentro del proceso de tu aplicación. PostgreSQL, en cambio, es un servidor independiente al que te conectas por red. De esa diferencia de arquitectura sale prácticamente todo lo demás: concurrencia, despliegue, tipos y herramientas.

¿SQLite es más rápido que PostgreSQL?

Para lecturas en un único proceso y escrituras pequeñas, casi siempre sí: SQLite se ahorra el viaje por red y toda la sobrecarga del protocolo cliente/servidor. Cuando hablamos de escrituras concurrentes desde muchos clientes, Postgres gana por goleada gracias a su bloqueo a nivel de fila y al MVCC. La pregunta de qué es "más rápido" depende más del tipo de carga que del motor en sí.

¿Puedo usar SQLite en producción?

Sí, siempre que la carga encaje. SQLite mueve sin problemas webs, aplicaciones de escritorio y dispositivos embebidos en producción. El límite real está en los escritores concurrentes: si tienes muchos procesos escribiendo a la vez, Postgres lo gestiona de forma nativa, mientras que SQLite serializa las escrituras. El modo WAL ayuda, pero no elimina la limitación.

¿Cómo migro de SQLite a PostgreSQL?

Exporta el esquema y los datos con sqlite3 mydb.db .dump y luego ajusta el SQL: AUTOINCREMENT se convierte en SERIAL o GENERATED AS IDENTITY, los nombres de tipos cambian y hay que limpiar algunas peculiaridades de SQLite, como el tipado laxo. Herramientas como pgloader automatizan casi todo el proceso. Eso sí, prepárate para reescribir cualquier cosa que dependiera del tipado flexible de SQLite.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR