SQLite y DuckDB: cuándo cada una es la opción correcta
Actualizado: 2026-07-07
SQLite y DuckDB son bases de datos embedded: ninguna requiere servidor, las dos trabajan sobre un archivo local. Pero su arquitectura es distinta. SQLite organiza datos por filas y destaca en transacciones cortas (OLTP); DuckDB organiza por columnas y brilla en análisis sobre grandes volúmenes (OLAP). Elegir la correcta, o combinarlas, es una ventaja técnica real.
SQLite[1] y DuckDB[2] comparten algo llamativo: las dos son bases de datos embebidas: una biblioteca que vive en tu proceso, sin servidor separado. Y sin embargo resuelven problemas distintos. SQLite es el rey de transacciones pequeñas y persistencia local; DuckDB es el rey del análisis columnar rápido sin infraestructura. Elegir mal entre ellas tiene coste real, y combinarlas cuando tiene sentido multiplica el valor de ambas.
El punto en común: embedded
Las dos descartan el modelo cliente-servidor. Tu aplicación importa la biblioteca y ejecuta SQL sobre un archivo. No hay systemd, ni puertos, ni usuarios, ni replicación como aspecto central. Esto reduce drásticamente la complejidad operativa:
-
SQLite: un archivo
.db(más algunos WAL temporales). Dumps, copias y migraciones soncp. -
DuckDB: un archivo
.duckdb(o en memoria, o directamente sobre Parquet).
Este patrón embedded es perfecto para apps móviles, desktop, servicios de una sola instancia, notebooks analíticos y pipelines ETL locales. Es el anti-patrón para sistemas con decenas de servicios concurrentes contra la misma base de datos.
Diferencia estructural: filas vs columnas
La separación no es cosmética. Es arquitectural:
-
SQLite guarda datos por filas. Cada fila es un bloque contiguo. Perfecto para
SELECT * FROM users WHERE id = 42: leer una fila entera es rápido. -
DuckDB guarda datos por columnas. Cada columna es un bloque contiguo. Perfecto para
SELECT AVG(amount) FROM transactions WHERE year=2023: recorre pocos campos de muchas filas.
OLTP vs OLAP, en formato embedded.
Diagrama comparativo de almacenamiento por filas (SQLite) vs por columnas (DuckDB) con ejemplos de queries óptimas para cada modelo
Cuándo elegir SQLite
Escenarios donde SQLite es claramente correcto:
-
App móvil con BD local: iOS, Android y desktop. SQLite es el estándar de facto en estas plataformas.
-
Configuración y persistencia de una app: Firefox, Chrome y decenas de aplicaciones lo usan así.
-
Servicio web con un solo nodo y lectura/escritura mixta moderada.
-
Prototipo o MVP antes de migrar a PostgreSQL.
-
Backup durable y transaccional local con ACID completo.
-
WASM en el navegador vía sql.js[3] o similares.
SQLite hace bien lo que debe hacer: transacciones pequeñas, alta integridad, baja latencia por operación.
Cuándo elegir DuckDB
Escenarios donde DuckDB brilla:
-
Análisis de logs: millones de filas, queries con agregados.
-
Consultar archivos Parquet/CSV directamente sin importar:
SELECT * FROM 'datos.parquet'funciona de serie. -
Reemplazar pandas en pipelines medianos, más eficiente en memoria y con SQL nativo.
-
Análisis ad-hoc en notebooks: Jupyter + DuckDB es una combinación muy potente.
-
Consolidar bases OLTP para reports sin tocar producción (CDC + DuckDB).
-
Procesamiento vectorizado sobre datos tabulares sin infraestructura distribuida.
DuckDB es, en la práctica, lo que pandas-con-SQL-nativo debería haber sido.
Python: las dos en la misma sesión
Ambas son triviales desde Python:
# SQLite — OLTP, persistencia transaccional
import sqlite3
con = sqlite3.connect('app.db')
con.execute("CREATE TABLE users (id INT, name TEXT)")
# DuckDB — OLAP, análisis rápido
import duckdb
con = duckdb.connect('analytics.duckdb')
# Consultar Parquet directamente, sin importar
df = con.execute("SELECT * FROM 'events.parquet' WHERE type='signup'").df()
DuckDB tiene integración Python especialmente pulida: DataFrames de pandas y Polars se consumen y producen sin overhead serio. Esta característica encaja bien con pipelines de datos que también usan Kafka para streaming de eventos.
Usarlas juntas
Combinarlas es un patrón muy productivo:
-
OLTP en SQLite, OLAP en DuckDB: la app escribe en SQLite; un job periódico vuelca cambios a DuckDB/Parquet para análisis.
-
DuckDB lee SQLite directamente con la extensión
sqlite_scanner:SELECT * FROM sqlite_scan('app.db', 'users'). Sin ETL manual. -
Archivar datos antiguos de SQLite a Parquet: DuckDB mantiene queries sobre históricos sin inflar la BD de producción.
El patrón "SQLite para caliente + DuckDB para frío" reduce complejidad mientras mantiene cada motor en su terreno óptimo.
Limitaciones reales
SQLite no es para:
-
Escrituras concurrentes altas; incluso con WAL, el write lock es global.
-
Múltiples procesos escribiendo simultáneamente (pueden aparecer race conditions sutiles).
-
Bases de datos muy grandes (>100 GB): técnicamente posible pero operacionalmente incómodo.
-
Replicación integrada: herramientas como Litestream[4] cubren este hueco.
DuckDB no es para:
-
OLTP real: sin locking fino, la concurrencia está diseñada para análisis.
-
Latencia sub-milisegundo (es rápido pero optimizado para queries analíticos).
-
Cargas con muchas escrituras concurrentes (ese no es su caso de uso).
Intentar que cada una haga lo del otro es hacerse daño innecesariamente.
Benchmarks orientativos
Con los debidos asteriscos (los benchmarks de BD son mentirosos sin contexto), órdenes de magnitud:
-
Aggregate sobre 1 millón de filas con GROUP BY: SQLite tarda unos 15 segundos. DuckDB lo hace en 1 segundo.
-
Scan de 100 millones de filas con filtro selectivo: SQLite va lento. DuckDB lo termina en segundos.
-
Transacciones concurrentes (con WAL): SQLite alcanza unas 1.000 transacciones por segundo. DuckDB no está pensado para esto.
Cada una es 10x o 100x más rápida que la otra en el terreno correcto.
El veredicto rápido
Cómo decidir en diez segundos:
-
¿Transacciones cortas, alta integridad, un proceso activo? SQLite.
-
¿Queries analíticos sobre grandes volúmenes, pocas escrituras? DuckDB.
-
¿App móvil, desktop o servicio simple? SQLite.
-
¿Notebooks, ETL local, reemplazar pandas? DuckDB.
-
¿Ambas cosas? Úsalas juntas.
Cualquier duda honesta se resuelve mirando la query principal: si es casi siempre un WHERE id=?, SQLite. Si es un GROUP BY sobre mucha fila, DuckDB. Para gestión de datos más amplia, ver también las bases de datos vectoriales cuando la búsqueda semántica entra en la ecuación.
Conclusión
SQLite y DuckDB son herramientas complementarias, no competidoras. Ambas representan la filosofía "embedded importa" aplicada a problemas diferentes. Para OLTP local, SQLite es imbatible por simplicidad y robustez. Para OLAP sin infraestructura, DuckDB ha hecho obsoletas muchas soluciones complejas. Conocer las dos y aplicar la correcta es una ventaja técnica real. Combinarlas cuando tiene sentido multiplica el valor de ambas.
Fuentes:
- SQLite — When to Use SQLite[5]
- DuckDB — Why DuckDB[6]
- Litestream — Streaming Replication for SQLite[4]
- sql.js — SQLite compiled to WebAssembly[3]