SQLite es la base de datos que la nube no esperaba — y está ganando de todas formas

Hay aproximadamente un billón de implementaciones activas de SQLite en el mundo. Ese número, proveniente de la propia documentación del proyecto SQLite, no es una estimación de marketing — es una realidad arquitectónica. Cada iPhone viene con SQLite. Cada dispositivo Android lo ejecuta. Firefox lo usa para almacenar historial, marcadores y cookies. Chrome lo utiliza como backend de base de datos. Skype, Dropbox, iTunes, VLC y toda la suite de Adobe Creative lo integran. La Biblioteca del Congreso de EE. UU. lo recomienda como formato de archivo. SQLite es, por cantidad de implementaciones, el motor de base de datos más utilizado en existencia — y hasta hace poco, la mayoría de los desarrolladores pensaban en él como algo que se envía dentro de aplicaciones móviles, no como infraestructura seria.
Esa perspectiva ahora está obsoleta. En 2026, SQLite se ejecuta dentro de la red global de borde de Cloudflare, potenciando aplicaciones distribuidas a través del fork libSQL de Turso, y formando la base de una arquitectura de aplicaciones local-first que está atrayendo atención seria de ingeniería. La base de datos que pasó treinta años siendo llamada "no apta para producción" está redefiniendo silenciosamente lo que significa producción.
Qué es realmente SQLite
SQLite es una biblioteca C — alrededor de 155,000 líneas — que implementa un motor de base de datos SQL completo en un solo archivo sin dependencias externas, sin proceso de servidor y sin configuración. Una base de datos es solo un archivo en disco. Abrirlo no requiere cadena de conexión, ni handshake de autenticación, ni un daemon en ejecución para conectarse. Enlazas la biblioteca, abres el archivo y ejecutas SQL. Eso es todo el proceso de configuración.
A pesar de su simplicidad, SQLite es totalmente compatible con ACID. Las escrituras son atómicas; las lecturas concurrentes son compatibles a través de su modo WAL (Write-Ahead Log); el formato en disco ha sido estable y totalmente compatible hacia atrás desde 2004. Soporta SQL-92 completo con la mayor parte de SQL:1999, incluyendo funciones de ventana, CTEs y operadores JSON añadidos en versiones más recientes. El proyecto es mantenido por un pequeño equipo bajo dedicación de dominio público — sin licencia, sin derechos de autor, sin acuerdos de colaboración.
Richard Hipp lo inició en 2000 para el programa de destructores de misiles guiados de la Armada de EE. UU., donde la ausencia de un administrador de base de datos era una restricción de diseño, no un descuido. Ese origen define todo sobre SQLite: fue construido para entornos donde no puedes permitirte un servidor, un DBA o conectividad de red. Esas limitaciones, resulta, describen el entorno de computación en el borde casi perfectamente.
SQLite en el borde: Cloudflare D1, Turso y LiteFS
Cloudflare D1, lanzado a disponibilidad general en 2023 y expandido sustancialmente durante 2024–2025, es SQLite ejecutándose dentro de Cloudflare Workers en más de 300 ubicaciones de borde en todo el mundo. Cuando un Worker ejecuta una consulta D1, se ejecuta contra un archivo SQLite ubicado en el nodo de borde más cercano al usuario. Las lecturas son de submilisegundos. La base de datos puede escalar a 10 GB por base de datos sin aprovisionamiento — creas una base de datos D1 con un comando de CLI y está inmediatamente disponible globalmente.
D1 resuelve el problema de escritura mediante un modelo primario-réplica: las escrituras van a una ubicación primaria y se replican asincrónicamente a todos los nodos de borde. Para cargas de trabajo con mucha lectura — que describe la mayoría de las aplicaciones web — la ventaja de latencia sobre una instancia de PostgreSQL de una sola región es sustancial. Cloudflare reporta que D1 sirve más de 50 mil millones de filas leídas por mes en su base de clientes a principios de 2026.
Turso, construido sobre libSQL — un fork de código abierto de SQLite mantenido por ChiselStrike — adopta un enfoque arquitectónico diferente. libSQL extiende SQLite con replicación nativa, modo servidor y soporte de API HTTP mientras mantiene la compatibilidad por cable con archivos SQLite estándar. Turso proporciona réplicas integradas: tu aplicación ejecuta una réplica local de SQLite que se mantiene sincronizada con una base de datos central, brindándote lecturas locales de latencia cero y consistencia eventual en las escrituras. El modelo está explícitamente diseñado para entornos de ejecución de borde y funciones serverless donde el costo de latencia de una llamada remota a la base de datos es prohibitivo.
LiteFS, desarrollado por Ben Johnson y ahora mantenido bajo el paraguas de Fly.io, adopta un enfoque basado en FUSE para la replicación de SQLite. Intercepta las escrituras del sistema de archivos a nivel del sistema operativo y replica el registro de write-ahead de SQLite a otros nodos a través de una capa de consenso. Las aplicaciones no requieren cambios de código — LiteFS se sitúa entre la aplicación y el sistema de archivos, sincronizando transparentemente bases de datos SQLite a través de un clúster de Fly.io. Fly.io Volumes, la capa de almacenamiento persistente para aplicaciones de Fly, combinada con LiteFS brinda a los desarrolladores una configuración distribuida de SQLite con failover automático y replicación en múltiples regiones.
SQLite sobre HTTP y los nuevos patrones de acceso
Uno de los desarrollos más interesantes en el ecosistema de SQLite es la aparición de capas de acceso basadas en HTTP que lo hacen comportarse más como una base de datos cliente-servidor tradicional sin renunciar a sus ventajas integradas. El modo servidor de libSQL expone una API WebSocket y HTTP a la que los clientes pueden conectarse de forma remota — lo que significa que se puede consultar una base de datos SQLite que se ejecuta en un servidor desde un navegador, una aplicación móvil o una función serverless utilizando semántica HTTP estándar.
Esto importa porque desbloquea SQLite para entornos donde no es posible integrar la biblioteca directamente. Una aplicación Next.js desplegada en Vercel no puede empaquetar una biblioteca nativa de SQLite — pero puede hacer solicitudes HTTP a una base de datos Turso y obtener resultados de consultas SQL como JSON. La experiencia del desarrollador es casi idéntica a consultar Postgres a través de un pool de conexiones, pero el motor subyacente es SQLite, con toda la simplicidad operativa que eso implica.
Bun, el entorno de ejecución de JavaScript que ha estado ganando tracción como una alternativa más rápida a Node.js, incluye soporte nativo de SQLite a través de su módulo bun:sqlite — sin necesidad de npm install, sin compilación de módulos nativos, sin node-gyp. const db = new Database("mydb.sqlite"); es toda la configuración. Las cifras de rendimiento que Bun cita para su implementación de SQLite — más de 4 millones de lecturas por segundo en una laptop — reflejan lo rápida que puede ser una base de datos sin sobrecarga de red cuando se ejecuta en el mismo proceso que el código de tu aplicación.
Arquitectura local-first y el auge de los CRDT
El movimiento local-first en el desarrollo de aplicaciones web se basa en una afirmación específica: que la arquitectura correcta para la mayoría de las aplicaciones es aquella donde la base de datos vive en el cliente, las lecturas son instantáneas porque acceden al almacenamiento local, y la sincronización con el servidor ocurre en segundo plano. La experiencia del usuario es más rápida, la capacidad fuera de línea está integrada y el servidor se convierte en un repetidor de sincronización en lugar de un cuello de botella de consultas.
SQLite es la opción natural para esta arquitectura porque se ejecuta en todas partes — en el navegador a través de WebAssembly (wa-sqlite, sql.js), en aplicaciones Electron de forma nativa, en móviles a través del SQLite integrado de la plataforma, y en nodos de borde a través de D1 o Turso. Las mismas consultas SQL funcionan en todos estos entornos contra archivos que son fundamentalmente compatibles entre sí.
El problema difícil en la arquitectura local-first es la resolución de conflictos: si dos clientes escriben ambos en una réplica local de SQLite mientras están fuera de línea, ¿cómo se fusionan esas escrituras cuando se reconectan? Aquí es donde entran en escena los CRDT (Tipos de Datos Replicados sin Conflictos). cr-sqlite, una extensión de SQLite desarrollada por Matt Wonlaw en Vlcn.io, implementa semántica CRDT directamente en SQLite instrumentando tablas SQL estándar con un reloj Lamport y una función de fusión. Dos bases de datos cr-sqlite se pueden fusionar de manera determinista sin una autoridad central. Cualquier conflicto a nivel de fila se resuelve mediante las reglas de fusión CRDT, no por un servidor que decide qué escritura gana.
Esta combinación — SQLite para almacenamiento, CRDT para semántica de fusión, un repetidor de sincronización para conectividad — es la arquitectura detrás de herramientas como ElectricSQL, Replicache y Zero (del equipo de Rocicorp que construyó Replicache). Ya no es puramente experimental: Linear, la herramienta de gestión de proyectos, utiliza una arquitectura basada en SQLite local-first para su aplicación de escritorio, y atribuye su sensación de rapidez precisamente al hecho de que cada interacción golpea una base de datos local en lugar de una API remota.
Herramientas para desarrolladores en 2026
El ecosistema de ORM y herramientas se ha puesto al día con el papel expandido de SQLite. Drizzle ORM, uno de los ORM de TypeScript de más rápido crecimiento, trata a SQLite como un objetivo de primera clase junto a PostgreSQL y MySQL — con adaptadores específicos para better-sqlite3, SQLite nativo de Bun, libSQL, D1 y Turso. La inferencia de tipos de Drizzle significa que tu esquema SQLite impulsa tus tipos de TypeScript sin sobrecarga en tiempo de ejecución.
Prisma agregó soporte para D1 en 2024 con su modelo de adaptadores de controladores, permitiendo que el motor de consultas de Prisma se ejecute contra Cloudflare D1 a través de la API HTTP de D1. La definición del esquema de Prisma permanece idéntica ya sea que estés apuntando a Postgres o D1; solo cambia la inicialización del cliente. better-sqlite3, el binding de Node.js para SQLite de Joshua Wise, sigue siendo la opción preferida para acceso síncrono y de alto rendimiento a SQLite en Node.js del lado del servidor — su diseño de API síncrona es una elección deliberada, que coincide con la naturaleza síncrona de SQLite y evita la sobrecarga asíncrona que afecta a la mayoría de los controladores de bases de datos.
Dónde SQLite realmente se queda corto
El modelo de un solo escritor de SQLite es su limitación arquitectónica más significativa. Solo se puede ejecutar una transacción de escritura a la vez — incluso en modo WAL, que permite lecturas concurrentes junto a un solo escritor, no puedes tener dos procesos escribiendo en la misma base de datos SQLite simultáneamente sin serialización. Para aplicaciones con alto rendimiento de escritura concurrente — un marcador que recibe miles de actualizaciones de puntuación por segundo, un sistema de mensajería con escrituras simultáneas de miles de clientes conectados — el modelo de escritura de SQLite es un muro duro.
El modo WAL ayuda significativamente para cargas de trabajo con muchas lecturas y escrituras ocasionales: los lectores nunca bloquean a los escritores y los escritores nunca bloquean a los lectores. Pero WAL no cambia la restricción fundamental de un solo escritor. Si tu cuello de botella es la concurrencia de escritura, necesitas una base de datos con un administrador de bloqueos diseñado para eso — PostgreSQL, MySQL o un sistema distribuido como CockroachDB.
Tampoco hay replicación incorporada. SQLite estándar no tiene concepto de primario/réplica, ni envío de WAL, ni ranuras de replicación lógica. Cada solución de replicación en el ecosistema — LiteFS, las réplicas integradas de Turso, cr-sqlite — es una capa construida sobre SQLite por terceros. Esto significa que las configuraciones de replicación conllevan más complejidad operativa de la que parecen: estás gestionando dos sistemas (SQLite más la capa de replicación) en lugar de uno. Y las garantías de consistencia varían: las réplicas integradas de Turso son eventualmente consistentes, no fuertemente consistentes — una escritura en una réplica puede no ser inmediatamente visible en otra.
El tamaño del archivo de la base de datos también se convierte en una consideración a escala. SQLite maneja bases de datos de decenas de gigabytes de forma rutinaria y se ha probado hasta cientos de gigabytes, pero a esa escala, pierdes parte de la simplicidad operativa que hace atractivo a SQLite. Mover un archivo SQLite de 50 GB con fines de copia de seguridad es una propuesta diferente a replicarlo a través de un flujo basado en registros.
Cuándo elegir SQLite, y cuándo no
SQLite es la opción correcta cuando tu relación lectura-escritura es alta, cuando quieres cero sobrecarga operativa, cuando estás construyendo para el borde o para arquitecturas local-first, o cuando estás enviando una herramienta para desarrolladores, CLI o aplicación integrada donde un servidor de base de datos sería absurdo. D1 y Turso lo han hecho viable para aplicaciones web de producción con usuarios globales, siempre que esas aplicaciones tengan muchas lecturas y puedan tolerar consistencia eventual en las escrituras.
PostgreSQL sigue siendo la opción correcta cuando necesitas una fuerte concurrencia de escritura, bloqueo a nivel de fila, topologías de replicación complejas o el ecosistema profundo de extensiones (PostGIS, pgvector, TimescaleDB) que Postgres ha construido durante treinta años. MySQL y MariaDB ocupan un territorio similar. Una base de datos distribuida como CockroachDB o PlanetScale está justificada cuando necesitas escalado horizontal de escritura con fuertes garantías de consistencia entre regiones — un caso de uso para el que SQLite nunca fue diseñado.
La pregunta más interesante para 2026 no es "SQLite vs. Postgres" sino "¿dónde pertenece cada uno en el mismo sistema?" Muchas arquitecturas de producción ahora usan ambos: SQLite en el borde para datos específicos del usuario con pocas escrituras (estado de sesión, preferencias, feeds por usuario) y Postgres en el centro para datos compartidos con muchas escrituras (transacciones, inventario, mensajería). La base de datos que la nube no esperaba ha encontrado su lugar en el stack — no reemplazando lo que vino antes, sino manejando los casos donde levantar un clúster de Postgres siempre fue la respuesta incorrecta.