Actualizado: 2026-07-07

SQLite lleva veinticinco años siendo la base de datos más desplegada del mundo, pero durante la mayor parte de ese tiempo se la consideró una opción de juguete para servidores. Esa percepción ha cambiado en los últimos tres años por una combinación de tres fuerzas: WAL maduro, discos NVMe generalizados en cualquier VPS barato, y proyectos como Litestream y libSQL que han resuelto las dos objeciones clásicas, la falta de replicación y la ausencia de acceso remoto. Este post recoge lo que funciona y lo que no después de varios años observándolo en producción.

Puntos clave

  • El modo WAL cambia SQLite de forma tan profunda que hablar de SQLite-sin-WAL y SQLite-con-WAL como la misma base de datos induce a error: la diferencia de concurrencia es de dos órdenes de magnitud en cargas web típicas.

  • Litestream transmite el WAL a un almacén de objetos compatible con S3 en tiempo casi real, lo que permite restauración a cualquier punto en el tiempo con pérdida máxima de pocos segundos.

  • libSQL, el fork de SQLite mantenido por Turso, añade replicación embebida sincronizada para arquitecturas distribuidas geográficamente.

  • SQLite cubre sin problema la mayoría de aplicaciones web con menos de mil usuarios concurrentes y bases por debajo de 100 GB.

  • No aplica cuando la carga tiene escritura concurrente intensa, cuando se necesita acceso multi-servidor al mismo archivo, o cuando se requieren extensiones avanzadas de Postgres.

El modo WAL cambia todo

La diferencia entre SQLite con el modo por defecto de diario por rollback y SQLite con WAL activado es tan grande que hablar de ambas como la misma base de datos induce a error. El modo rollback serializa escrituras y lecturas en un único bloqueo de archivo, lo que limita la concurrencia útil a un puño de consultas por segundo. El modo WAL, escritura hacia adelante en un archivo separado, permite lecturas concurrentes mientras hay una escritura activa, y limita las colisiones a escritores simultáneos, tal y como documenta el propio proyecto SQLite[1]. Para aplicaciones web con relación 95 a 5 entre lecturas y escrituras, la diferencia de rendimiento es de dos órdenes de magnitud.

Activar WAL es una sola instrucción en tiempo de apertura de la base, pero tiene implicaciones que conviene conocer:

  • El archivo WAL crece mientras hay transacciones activas y se compacta automáticamente cuando alcanza un umbral (mil páginas por defecto, según la documentación de SQLite). En cargas con escrituras muy frecuentes conviene ajustar ese umbral hacia arriba.

  • El archivo WAL y el archivo principal deben compartir sistema de archivos; intentar ponerlos en volúmenes distintos es un error clásico que rompe la atomicidad.

La segunda clave del rendimiento en servidor es ajustar el tamaño de página y la caché. SQLite usa páginas de 4 KB por defecto, que encaja bien con la mayoría de cargas, pero para tablas con filas pequeñas y muchas lecturas aleatorias, subir a 8 KB o 16 KB al crear la base puede mejorar la eficiencia de la caché del sistema de archivos.

Litestream y la replicación fue el punto de inflexión

El talón de Aquiles histórico de SQLite en servidor era la copia de seguridad. Hasta la llegada de Litestream[2] en 2021, la única forma decente de respaldar una base activa era parar escrituras, copiar el archivo y reanudar. En cualquier sistema con tráfico real eso no es viable. Litestream resolvió el problema transmitiendo el WAL a un almacén de objetos compatible con S3 en tiempo casi real (el intervalo de sincronización por defecto del agente es de un segundo), lo que permite restauración a cualquier punto en el tiempo con una pérdida máxima de pocos segundos. Dejo el desglose completo de su funcionamiento en Litestream: replicación casi en tiempo real para SQLite.

Lo que empezó como un truco ingenioso se ha convertido en la pieza que hace viable SQLite en producción seria. En los proyectos desplegados, Litestream apuntando a un bucket S3 compatible como Hetzner Object Storage o Cloudflare R2 cuesta algunos céntimos al mes en almacenamiento y protege frente al fallo del disco o la destrucción del servidor. El proceso de restauración es un comando: descarga el estado del bucket, reconstruye la base al instante elegido y lanza la aplicación.

La evolución más reciente es libSQL, el fork de SQLite que mantiene Turso y que ya es la base de producción de Turso Cloud. Añadió replicación embebida sincronizada, permitiendo una base primaria en servidor y réplicas locales en cada cliente o en nodos regionales. Para aplicaciones distribuidas geográficamente, libSQL resuelve el problema de la lectura local sin tener que correr Postgres multi-región. Conviene no confundirlo con Turso Database (antes conocido como Limbo), la reescritura completa de SQLite en Rust que la misma compañía mantiene en GitHub[3]: a mediados de 2026 sigue en fase beta camino de su primera versión estable, según el propio blog de Turso[4], así que para producción hoy la opción madura sigue siendo libSQL, no la reescritura.

Cargas donde SQLite sigue siendo la mejor opción

SQLite en servidor con WAL y Litestream cubre sin pestañear la mayoría de aplicaciones web con menos de mil usuarios concurrentes y bases por debajo de 100 GB. Esto incluye muchos sistemas de gestión, paneles internos, sitios con contenido dinámico moderado, APIs de tamaño medio y prácticamente cualquier cosa que no sea una tienda con picos masivos o una red social con escritura intensiva. El caso de éxito más visible es el propio sqlite.org, que según la documentación oficial del proyecto[5] sirve su sitio entero desde una base SQLite atendiendo entre 400.000 y 500.000 peticiones HTTP al día, de un 15-20% dinámicas, corriendo en una única VM que comparte servidor físico con otras 23.

El segundo nicho donde brilla es el desarrollo y las pruebas. Poder reemplazar Postgres por SQLite en el entorno de integración continua acelera el tiempo de arranque de los tests de decenas de segundos a menos de dos. La mayor parte del SQL estándar es compatible, y cuando algo se desvía se detecta pronto.

El tercer espacio es el de aplicaciones de escritorio y móvil que sincronizan con la nube. Con libSQL y su sincronización bidireccional el patrón de tener una base local en el cliente que replica con un servidor central se ha simplificado drásticamente.

Donde SQLite sigue siendo mala idea

Hay casos donde SQLite en servidor no compensa y conviene ser honesto:

  • Carga con escritura concurrente intensa sostenida: SQLite serializa escritores por diseño. Un sistema con cientos de transacciones de escritura por segundo va a tocar techo. Postgres, MariaDB o incluso MySQL con InnoDB pueden absorber órdenes de magnitud más de escritura concurrente.

  • Arquitectura multi-proceso con varios servidores de aplicación accediendo al mismo archivo: SQLite no está pensado para accesos por red al archivo. El bloqueo a través de NFS es poco fiable y ha sido fuente de corrupciones en proyectos reales. Si tu arquitectura requiere más de un servidor leyendo y escribiendo contra la misma base, SQLite no es la herramienta adecuada, punto.

  • Necesidad de funciones avanzadas de Postgres: extensiones geoespaciales serias, búsqueda de texto completo de producción, o soporte transaccional para dos fases. La brecha con Postgres en estas áreas es sustancial.

  • Carga mayoritariamente analítica sobre grandes volúmenes: si lo que hay detrás son agregaciones y escaneos columnares más que transacciones de fila, el motor correcto suele ser otro; repaso ese cruce en SQLite y DuckDB: cuándo cada una es la opción correcta.

Esta misma lógica de elegir la herramienta correcta para la carga correcta aplica al debate Citus para escalar Postgres horizontalmente: cada base de datos tiene su rango de fortalezas.

Cuándo compensa

La pregunta ya no es si SQLite puede sostener un servidor web, porque puede. La pregunta es si tu caso concreto encaja en su perfil de fortalezas. Si tu aplicación:

  • Lee mucho más de lo que escribe.

  • Cabe en un solo servidor.

  • No necesita replicación síncrona multi-nodo.

  • Valora la simplicidad operativa de un archivo sin proceso servidor.

Entonces SQLite con WAL y Litestream es probablemente la opción de menor coste total en ingeniería y operación.

Si por el contrario tu sistema crecerá a varios servidores, tendrá escritura concurrente alta, o ya tienes Postgres funcionando sin dolor, no hay razón para cambiar. La gracia de SQLite en 2025 no es que haya sustituido a Postgres, sino que ha dejado de ser una opción excéntrica para cierto rango de problemas. Ese rango es más grande de lo que mucha gente supone.

Conclusión

SQLite con WAL y Litestream puede ahorrar semanas de montaje de infraestructura que no aportan nada para un servicio que va a tener 200 usuarios activos al mes. Tomárselo en serio antes de asumir que necesitas una base de datos separada es parte de la ingeniería práctica.

También en inglés: SQLite in production: patterns that have aged well.

Fuentes

  1. tal y como documenta el propio proyecto SQLite
  2. Litestream
  3. en GitHub
  4. el propio blog de Turso
  5. según la documentación oficial del proyecto
  6. Litestream — How It Works