Qué es D1: SQLite servida en el edge
D1 es la base de datos SQL nativa de Cloudflare: un motor SQLite gestionado y sin servidor que se consume como un binding en env. Qué significa serverless y gestionada aquí, por qué está en GA, para quién está pensada —aplicaciones intensivas en lectura con usuarios globales— y cómo la replicación de lectura acerca los datos a cada usuario del planeta.
Durante años, poner una base de datos relacional cerca de tus usuarios fue un lujo caro: elegías una región, provisionabas un servidor, gestionabas conexiones y rezabas para que la latencia hacia esa única caja no arruinara la experiencia de quien estaba al otro lado del mundo. D1 borra ese problema de un plumazo. Es SQLite —el motor de base de datos más desplegado del planeta— convertido en un servicio gestionado y sin servidor, que tu Worker consume como un binding más en env. Ni provisionas, ni conectas, ni administras: declaras y consultas.
- Entender qué es D1 y qué añade la plataforma sobre el motor SQLite.
- Precisar qué significan serverless y gestionada en este contexto.
- Situar para quién está pensada: cargas intensivas en lectura con alcance global.
- Conocer la replicación de lectura como la pieza que la acerca a cada usuario.
SQLite, pero sin servidor que gestionar
SQLite no es una base de datos de juguete: es una biblioteca embebida, de un solo archivo, probada en miles de millones de dispositivos, con soporte completo de SQL, transacciones ACID e índices. Su límite histórico nunca fue el motor, sino la operación: vive en un fichero local y, por sí solo, no sabe replicarse, escalar ni sobrevivir a la caída de la máquina que lo aloja. D1 toma ese motor y le pone alrededor todo lo que le faltaba para ser un servicio —almacenamiento durable, copias de seguridad, replicación y escalado— sin que tú toques nada de eso.
Que sea serverless significa que no existe un servidor que aprovisionar, dimensionar ni parchear: no hay instancias, ni pools de conexión que agotar, ni una factura por horas de una máquina encendida esperando tráfico. Que sea gestionada significa que la durabilidad, las copias y la distribución son responsabilidad de la plataforma. Lo único que tú ves es un objeto en env con métodos para preparar y ejecutar SQL.
export default {
async fetch(request, env, ctx): Promise<Response> {
// env.DB es un D1Database: SQLite gestionado, listo para consultar
const { results } = await env.DB.prepare('SELECT id, titulo FROM articulos LIMIT 10').all();
return Response.json(results);
},
} satisfies ExportedHandler<Env>;
En 2026 D1 está en disponibilidad general (GA): no es un experimento ni una beta con asteriscos, sino un producto listo para producción, con límites documentados, garantías de durabilidad y un lugar de primera clase en la plataforma. Puedes construir sobre ella sin miedo a que cambie bajo tus pies.
Bajo el capó sigue siendo SQL estándar de SQLite, así que no aprendes un dialecto exótico: CREATE TABLE, JOIN, subconsultas, índices, vistas, disparadores y transacciones se comportan como cabría esperar, y casi todo lo que ya sabes de SQL relacional se transfiere intacto. Lo que cambia no es el lenguaje con el que hablas a la base, sino la forma en que la base llega hasta ti.
Para ti, eso tiene una consecuencia práctica inmediata: cualquier conocimiento de SQL que ya tengas, cualquier tutorial de SQLite y casi cualquier herramienta de su ecosistema te sirven tal cual, porque debajo hay exactamente ese motor y no una reinvención parecida.
Que la plataforma administre la durabilidad no es solo comodidad: te regala capacidades que en un SQLite local tendrías que montar a mano. D1 guarda un historial y ofrece recuperación a un punto en el tiempo —Time Travel— de hasta treinta días atrás mediante marcadores, de modo que un borrado accidental o una migración desastrosa dejan de ser una catástrofe irreversible. No hay que programar copias ni un cron de respaldo: el historial existe porque el servicio lo mantiene por ti.
Para quién es: aplicaciones intensivas en lectura
D1 no pretende ser cualquier base de datos para cualquier carga. Está afinada para un patrón concretísimo y muy común: aplicaciones intensivas en lectura —muchas más consultas que escrituras— con usuarios repartidos por el mundo. Un catálogo de comercio electrónico, un gestor de contenidos, la configuración de una aplicación, un blog con tráfico global: todos leen constantemente y escriben de vez en cuando.
La pieza que hace brillar a D1 en ese escenario es la replicación de lectura. La base tiene una copia primaria que acepta escrituras, y la plataforma crea automáticamente réplicas de solo lectura en varias regiones. Un usuario en Tokio lee de una réplica cercana en lugar de cruzar el planeta hasta la primaria. Se activa con la Sessions API, que garantiza consistencia secuencial dentro de una sesión: nunca leerás un dato más viejo del que ya habías visto.
// una sesion enruta las lecturas a una replica cercana, con consistencia secuencial
const marca = request.headers.get('x-d1-bookmark') ?? 'first-unconstrained';
const session = env.DB.withSession(marca);
const { results } = await session.prepare('SELECT * FROM productos WHERE categoria = ?').bind('bebidas').all();
flowchart LR U[Usuario en Tokio] --> RE[Replica de lectura cercana] RE -.sirve lecturas.-> U ESC[Escritura] --> PR[Base primaria] PR -.propaga a.-> RE style RE fill:#a6e3a1,color:#11111b style PR fill:#fab387,color:#11111b
Conviene entender la asimetría que sostiene ese modelo. Las escrituras van siempre a la primaria, la única copia autoritativa; las lecturas se reparten entre las réplicas cercanas. Por eso D1 rinde de maravilla cuando las lecturas dominan: cada escritura sigue pagando su viaje a la primaria, pero se amortiza entre las miles de lecturas que una réplica resuelve al lado del usuario. Si tu carga invirtiera esa proporción —escritura constante y masiva—, esa única primaria sería el cuello de botella, y ahí es donde D1 deja de ser la herramienta idónea.
Encaja de maravilla
Catálogos, CMS, blogs, configuración, perfiles: mucha lectura, escritura ocasional y usuarios globales que agradecen una réplica cerca.
Piénsatelo dos veces
Cargas con escritura masiva y constante, conjuntos de datos enormes o necesidad de una extensión concreta de otro motor: ahí otra pieza puede encajar mejor.
Una réplica de lectura puede ir un instante por detrás de la primaria, porque la escritura tarda un momento en propagarse. La Sessions API acota ese riesgo dentro de una sesión —nunca lees algo más viejo de lo que ya viste—, pero entre sesiones distintas eres tú quien decide qué consistencia necesitas, arrastrando el marcador de una a otra cuando importa. Para un catálogo, ese desfase de milisegundos es irrelevante; para un saldo que acabas de modificar y quieres releer al instante, conviene leer desde la primaria o mantener viva la sesión.
Un ejemplo concreto aterriza todo esto. Imagina una tienda con clientes en cinco continentes: el catálogo se lee millones de veces al día y solo cambia cuando el equipo actualiza precios o existencias. Con D1, cada visitante lee la ficha de un producto desde una réplica a pocos milisegundos, mientras que la actualización ocasional del catálogo viaja hasta la primaria. Es el patrón intensivo en lectura en estado puro, y es exactamente para lo que D1 fue diseñada.
Dónde encaja entre KV, R2 y Durable Objects
D1 no compite con el resto del almacenamiento de la plataforma: lo complementa. Cada pieza responde a una forma distinta de la pregunta dónde viven los datos, y elegir bien es la mitad del diseño en el edge.
- KV es un almacén clave-valor de lectura global y consistencia eventual: perfecto para datos que se leen muchísimo y cambian poco, pero sin consultas relacionales.
- R2 guarda objetos —imágenes, vídeos, ficheros— sin cargos de egress, no filas que consultar con SQL.
- Durable Objects ofrece estado coordinado con identidad única y consistencia fuerte: ideal para contadores, salas o sesiones, no para consultas sobre tablas.
- D1 es la respuesta cuando necesitas SQL de verdad: tablas,
JOIN, índices, transacciones y consultas expresivas sobre datos relacionados.
Un JOIN lo deja claro: cuando tus datos tienen relaciones, D1 las resuelve donde viven —en la base— en lugar de traerlo todo al Worker y cruzarlo a mano, como obligaría un almacén clave-valor.
-- las relaciones se consultan en la base, no en memoria del Worker
SELECT u.email, count(p.id) AS pedidos
FROM usuarios u
LEFT JOIN pedidos p ON p.usuario_id = u.id
GROUP BY u.id
ORDER BY pedidos DESC;
KV, R2, Durable Objects y D1 no forman un ranking donde uno gana: forman un repertorio. La destreza en el edge consiste en leer la forma de tus datos y su patrón de acceso, y colocar cada cosa donde su modelo brilla. Un mismo proyecto suele usar varias a la vez: R2 para los archivos, KV para la caché de lectura, D1 para el modelo relacional y Durable Objects para el estado en tiempo real. D1 es tu elección cuando la palabra clave es relación entre datos.
Al ser serverless, D1 no cobra por una máquina encendida esperando tráfico: su facturación se mide en filas leídas y escritas, más el almacenamiento. Esa unidad alinea el precio con el uso real y premia el buen modelado —un índice que evita un escaneo completo no solo acelera la consulta, también la abarata, porque lee menos filas—. Pensar en cuántas filas toca cada consulta deja de ser solo cuestión de rendimiento y pasa a ser también de coste.
Por qué D1 redefine la base de datos en el edge
Durante décadas, la base de datos fue el ancla que fijaba tu arquitectura a un punto del mapa. Podías desplegar el compute donde quisieras, pero al final todo peregrinaba hasta esa única caja en una región para leer una fila, y esa peregrinación —cien, doscientos milisegundos de ida y vuelta— era el techo real de tu latencia por mucho que el resto corriera en el edge. D1 rompe ese ancla, y lo hace con una decisión de diseño más sutil de lo que parece: en lugar de inventar un motor distribuido nuevo y frágil, tomó el motor más probado y aburrido que existe —SQLite, que ya llevaba la sencillez en el nombre— y puso la inteligencia distribuida alrededor, no dentro. Esa elección tiene consecuencias profundas. Como cada base D1 es, en el fondo, un SQLite, hereda su fiabilidad, su semántica conocida y su enorme superficie de compatibilidad; y como la replicación vive en la plataforma y no en el motor, Cloudflare puede crear réplicas de lectura donde el tráfico las pida, activarlas y apagarlas solo, y enrutar a cada usuario a la copia más cercana sin cobrarte por ello ni pedirte que gestiones nada. La Sessions API es la costura elegante entre las dos mitades: te deja aprovechar las réplicas sin caer en las trampas clásicas de la consistencia eventual, porque garantiza que dentro de una sesión nunca retrocedas en el tiempo, que nunca leas un dato más viejo del que ya habías visto. El resultado es que la pregunta que gobernaba el diseño —en qué región pongo la base de datos— se disuelve para el caso intensivo en lectura y se sustituye por otra mucho más sana: cómo modelo mis datos para que la mayoría de los accesos sean lecturas que una réplica cercana pueda servir. Ese cambio de pregunta es, en el fondo, todo el track del edge condensado en una pieza: el compute ya estaba cerca del usuario; ahora los datos, por fin, también pueden estarlo.
- Explica en una frase qué añade D1 sobre un SQLite corriendo en un fichero local.
- Distingue serverless de gestionada: ¿qué desaparece de tu trabajo en cada caso?
- Piensa en una aplicación que uses: ¿es intensiva en lectura? ¿Se beneficiaría de réplicas cercanas a cada usuario?
- Para tres tipos de datos —un catálogo, un vídeo y un contador en vivo— decide si van a D1, R2 o Durable Objects y justifica por qué.