+250 skills, dinamita para tu productividad 🧨Explorar →

Guía para empezar en Cloudflare: Workers, D1, R2 y Queues

No he desplegado nada serio en Cloudflare.

Ni una API, ni una base de datos en D1, ni un Durable Object. Lo más cerca que he estado ha sido destripar el código de Cloudflare OS o leer cómo celld ejecuta Durable Objects fuera de Cloudflare. Y cada vez que entro en el dashboard me pasa lo mismo: una barra lateral con veinte productos, todos con nombre propio, y ninguna pista de por cuál se empieza.

Así que hice lo que haría cualquiera que no ha empezado con Cloudflare: le pedí a la IA que me lo explicara. No un «hola mundo», sino un mapa. Qué pieza hace qué, en qué orden aparece cada una cuando construyes una webapp con usuarios de verdad y cuánto cuesta cada una.

Este post es esa guía, ordenada, recortada y contrastada con la documentación oficial. No es experiencia de producción. Es el mapa que me habría gustado tener antes de escribir la primera línea, y si tú tampoco has tocado Cloudflare, está pensado para ti.

La idea de partida es de Flavio Copes en The Cloudflare products I actually use: empezar por un problema real y elegir la pieza más pequeña de Cloudflare que lo elimine. Con un giro: aquí el objetivo es aprender la plataforma, así que cuando Cloudflare tenga una solución razonable, se prueba antes de salir de ella. Sin meter productos a calzador, eso sí.

En este artículo vas a encontrar:

  • El modelo mental que ordena todo lo demás: un Worker en el centro y los servicios enchufados con bindings
  • Qué le pasa a una request desde que sale del navegador hasta que llega (o no) a tu código
  • Dónde va cada dato: D1, KV, R2, Durable Objects o Analytics Engine
  • Cómo se montan el registro, el login y la protección contra bots y abusos
  • Cuánto cuesta de verdad y hasta dónde se llega con el plan de 5 dólares

🧭 Precios, límites y estado de cada producto revisados contra developers.cloudflare.com el 18 de septiembre de 2026. La guía que generó la IA acertaba en casi todo, pero tenía dos datos mal que aquí están corregidos. Cloudflare cambia cifras a menudo: revisa las fuentes del final antes de decidir nada con dinero de por medio.

¿Qué es Cloudflare hoy, si ya no es solo un CDN?

Cloudflare puede ser la plataforma donde vive la aplicación entera: el código se ejecuta en Workers, el frontend se sirve con Static Assets, los datos van a D1, KV y R2, el trabajo en segundo plano a Queues y Workflows, y hay piezas propias para correo, analítica, logs e IA.

Durante años fue otra cosa. Era la capa que ponías delante de tu servidor: DNS, proxy, CDN, certificados TLS, caché y protección. Tu aplicación vivía en otro sitio y Cloudflare hacía de portero.

Ese portero ahora tiene la casa entera.

El concepto que hay que meterse en la cabeza antes que ningún producto es el de binding. Un binding conecta un Worker con un recurso de la plataforma, y dentro de tu código ese recurso aparece como una variable más del entorno: env.DB es tu base de datos, env.FILES tu bucket de archivos, env.TASKS tu cola. No hay URLs con tokens, ni clientes HTTP entre servicios, ni credenciales que rotar. La documentación de Cloudflare recomienda bindings frente a sus APIs REST cuando el Worker y el recurso están dentro de la plataforma.

Piensa en los enchufes de la pared frente a un alargador que tiras desde el piso de al lado. Los dos dan corriente, pero uno viene de serie con la casa.

Navegador Edge de Cloudflare · DNS · TLS · CDN y caché · WAF Worker tu código: API, SSR, lógica no invoca el Worker Static Assets HTML, CSS, JS Cron Triggers lo despierta a su hora bindings Datos D1 SQL relacional KV clave-valor global R2 archivos y objetos Images redimensiona y optimiza Procesos Queues encola trabajo Workflows procesos con pasos Durable Objects coordina una entidad Email Service envía y recibe correo Observar Analytics Engine eventos de producto Workers Logs qué pasó en cada ejecución Workers Traces dónde se fue el tiempo IA AI Gateway observa y limita Workers AI ejecuta modelos Vectorize busca por similitud Cada binding llega al Worker como una variable de env, sin URLs ni credenciales

Que el mapa no te asuste. Ninguna request recorre todo eso. El Worker es el centro de composición y cada funcionalidad tira solo de los bindings que necesita: el login toca D1 y poco más, la subida de un avatar toca R2 e Images, y un endpoint de salud no toca nada.

La primera versión de la aplicación debería ser mucho más pequeña: un Worker con Static Assets, D1 para los datos, R2 para los archivos, Turnstile y Rate Limiting para protegerse, y una Queue que mande los emails. Con eso ya tienes frontend, API, registro, login, datos relacionales, archivos, correo y tareas asíncronas.

🔑 El resto de productos aparece por crecimiento, no por anticipación. Cada uno entra el día que la aplicación tiene el problema que resuelve.

El recorrido de una request desde el navegador hasta tu código

La request pasa primero por el DNS de Cloudflare, después por su edge (donde se aplican TLS, reglas del firewall y caché) y solo si hace falta llega a tu Worker. Esa última condición es la que más afecta al rendimiento y a la factura.

DNS. Cloudflare ofrece DNS autoritativo gratis y no cobra ni limita las consultas en los planes Free, Pro y Business. Su trabajo es que app.tudominio.com apunte a quien tiene que responder. Tenerlo aquí te da una entrada estable: puedes cambiar toda la infraestructura de detrás sin tocar el dominio.

El proxy. Es la famosa nube naranja al lado de cada registro DNS. Con el proxy activado, el tráfico HTTP ya no va directo a tu origen: pasa antes por Cloudflare. Y ahí cambia el papel de Cloudflare, que deja de ser una guía telefónica y pasa a estar en el camino de cada request. Por eso puede aplicar TLS, caché, firewall, protección DDoS o ejecutar tu Worker.

Universal SSL. Una vez el dominio está activo, Cloudflare emite y renueva certificados TLS automáticos, también en el plan Free. Cubren el dominio raíz y los subdominios de primer nivel: tudominio.com, www.tudominio.com, app.tudominio.com. Adiós a certbot, a la tarea de renovación y a la configuración de nginx para los certificados.

WAF. El firewall de aplicaciones web inspecciona las requests antes de que lleguen a tu código. En el plan Free hay un conjunto de reglas gestionadas que frena ataques comunes. No sustituye a tus validaciones: el WAF frena el tráfico malicioso evidente y tu Worker aplica las reglas de producto y los permisos.

Navegador GET /app.js · POST /api/login DNS de Cloudflare registro con proxy activado tu dominio resuelve a Cloudflare, no a tu servidor Edge TLS · WAF · caché Universal SSL emite y renueva el certificado reglas gestionadas gratis: frena lo claramente malicioso ¿Es un asset estático o está en caché? no Responde el edge Static Assets o respuesta cacheada gratis, no invoca el Worker Se ejecuta el Worker API, SSR, login, lógica cuenta: 1 request + ms de CPU /app.js, /logo.svg → edge · /api/projects, /login → Worker

Quédate con la bifurcación final, porque es la que decide la factura. No toda request debería convertirse en ejecución de código. Las requests que solo sirven Static Assets son gratis e ilimitadas y no se cobra el almacenamiento de esos archivos. Solo cuentan como Workers las que invocan tu Worker.

Hay una excepción documentada. Si configuras run_worker_first para que tu código intercepte también los assets, esas requests pasan a contar como invocaciones del Worker, y en el plan Free devuelven un 429 cuando superas el límite diario. Úsalo solo si de verdad necesitas lógica delante de los assets (autenticación, por ejemplo).

Guía interactiva gratis

Del mapa a tu primer proyecto construido con IA

Si vas a montar tu webapp con un agente, el curso te lleva paso a paso: elegir un proyecto pequeño, escoger agente y presupuesto, y pasar por el modo plan antes de tocar una línea. Son 17 paradas y eliges tú el camino.

Entra en el curso gratis →

¿Workers o Pages para empezar un proyecto nuevo?

Workers con Static Assets. Lo dice la página de buenas prácticas de Workers: si empiezas un proyecto nuevo, usa Workers en lugar de Pages. Pages sigue funcionando y no está deprecado, pero «las nuevas funcionalidades y optimizaciones se concentran en Workers».

Muchos tutoriales, incluidos algunos muy recientes, siguen montando todo con Pages y Pages Functions. No están mal para proyectos que ya existen, pero para uno nuevo el camino es otro: un único despliegue que contiene tu frontend compilado en /dist y tu Worker en /src, y Cloudflare los despliega juntos como una unidad. Si quieres ver un proyecto real montado así, EmDash, el CMS de Cloudflare sobre Astro, se despliega sobre Workers, D1 y R2.

Un Worker puede hacer de muchas cosas a la vez: API, backend, BFF, middleware, aplicación SSR, receptor de webhooks, consumidor de una cola o tarea programada. En una arquitectura Cloudflare-first no piensas en «mi servidor web y además unos Workers». El Worker es el runtime de la aplicación.

Plan gratis o plan de 5 dólares

El plan Workers Free incluye 100.000 requests al día y 10 ms de CPU por invocación. Para un prototipo va sobrado.

El plan Workers Paid cuesta 5 dólares al mes por cuenta e incluye 10 millones de requests y 30 millones de milisegundos de CPU al mes. A partir de ahí cobra 0,30 dólares por millón de requests y 0,02 dólares por millón de milisegundos de CPU. Cada invocación puede usar hasta 5 minutos de CPU (30 segundos por defecto, ampliable en la configuración).

Cloudflare no cobra el tiempo de reloj en Workers, cobra requests y CPU. Si tu Worker se pasa 300 ms esperando a que responda una API externa, esa espera no te cuesta nada. Solo pagas los milisegundos en los que el procesador trabaja de verdad.

¿Mi recomendación, desde la teoría? Pagar los 5 dólares desde el primer día si el objetivo es aprender. No porque vayas a necesitar 10 millones de requests, sino porque varios productos tienen límites o capacidades distintas en Free y no quieres que esos límites te condicionen el diseño a cada paso. El caso más claro es el correo: enviar emails a cualquier destinatario con Email Service exige el plan Paid.

Wrangler: la infraestructura vive en un archivo

Wrangler es la CLI de Cloudflare y la herramienta con la que describes y operas la aplicación: desarrollo en local, despliegues, bindings, variables, secretos, bases de datos D1, colas, buckets, crons y observabilidad. Todo lo que conecta tu Worker con el resto de la plataforma queda declarado en un archivo, wrangler.jsonc, al lado del código.

La alternativa es crear recursos a mano en el dashboard y olvidar tres semanas después cómo estaban conectados. Ya sabes cómo acaba eso.

Así se vería el archivo de configuración de la versión mínima de la aplicación, con la sintaxis que documenta Cloudflare:

{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "mi-webapp",
  "main": "src/index.ts",
  "compatibility_date": "2026-09-18",

  // Frontend compilado: se sirve sin invocar el Worker
  "assets": { "directory": "./dist", "binding": "ASSETS" },

  // Datos relacionales y archivos
  "d1_databases": [
    { "binding": "DB", "database_name": "mi-webapp", "database_id": "<id-de-la-base>" }
  ],
  "r2_buckets": [{ "binding": "FILES", "bucket_name": "mi-webapp-files" }],

  // La misma Worker produce y consume la cola de emails
  "queues": {
    "producers": [{ "binding": "TASKS", "queue": "mi-webapp-tasks" }],
    "consumers": [{ "queue": "mi-webapp-tasks", "max_retries": 5 }]
  },

  // 10 intentos de registro por minuto y clave
  "ratelimits": [
    { "name": "SIGNUP_LIMIT", "namespace_id": "1001", "simple": { "limit": 10, "period": 60 } }
  ],

  // Limpieza diaria a las 03:00 UTC
  "triggers": { "crons": ["0 3 * * *"] },

  "observability": { "enabled": true }
}

Cada entrada con binding aparece luego en el código como una propiedad de env, y con TypeScript puedes tiparlas:

// Lo que el runtime inyecta en cada handler
interface Env {
  ASSETS: Fetcher;
  DB: D1Database;
  FILES: R2Bucket;
  TASKS: Queue;
  SIGNUP_LIMIT: RateLimit;
  SESSION_SECRET: string;
}

Ese SESSION_SECRET del final no está en el archivo de configuración, y es a propósito. Los secretos no van a Git. La separación que propone Cloudflare es sencilla:

Qué es Dónde vive
Configuración pública (nombres, límites, crons) wrangler.jsonc
Secreto de un Worker concreto Worker Secret (wrangler secret put SESSION_SECRET)
Secreto que comparten varias aplicaciones Secrets Store, a nivel de cuenta

Con eso no necesitas un gestor de secretos externo para empezar.

Si te gusta tener la infraestructura a la vista y junto al código, en la newsletter compartimos cada domingo 12 recursos sobre herramientas y productividad con IA para developers. Ya somos +7.200.

Quiero esa dinamita 🧨

¿Dónde guardo cada dato: D1, KV o R2?

Los datos con tablas y relaciones van a D1, los archivos a R2 y la configuración que se lee mucho y cambia poco a KV. Hay dos destinos más para casos concretos: Durable Objects cuando varios usuarios tocan la misma cosa a la vez y Analytics Engine para eventos que quieres contar. Si metes un saldo en KV o un PDF en D1, más adelante te toca migrar datos en producción.

Si tu dato… …va a tiene tablas, relaciones y filtros users, sessions, projects, invitations D1 la fuente de verdad, sobre SQLite es un archivo o un binario PDFs, avatares originales, exports, ZIPs R2 el archivo en R2, sus metadatos en D1 se lee mucho, cambia poco y tolera retraso feature flags, configuración, respuestas cacheadas KV clave-valor global, consistencia eventual lo tocan varios usuarios a la vez una sala de chat, un quiz en directo, un documento Durable Object un punto único de coordinación por entidad es un evento que quieres contar feature usada, 429 recibido, tokens gastados Analytics Engine eventos de alta cardinalidad, consulta SQL Nunca en KV: saldos, stock, pagos confirmados ni permisos que se revocan al instante. Una escritura puede tardar en verse en otras regiones. No es un bug, es el modelo de KV.

D1: la base de datos de la aplicación

D1 es la base de datos SQL serverless de Cloudflare, construida sobre SQLite. Aquí van usuarios, sesiones, perfiles, organizaciones, proyectos, comentarios, invitaciones y todo lo que tenga relaciones, índices, restricciones y joins.

Los números del plan Free son 5 millones de filas leídas al día, 100.000 escritas y 5 GB de almacenamiento en total, con un máximo de 500 MB por base. En Paid el techo por base sube a 10 GB y el mes incluye 25.000 millones de filas leídas y 50 millones escritas; a partir de ahí, 0,001 dólares por millón de lecturas y 1 dólar por millón de escrituras.

Ojo a dos cosas.

D1 cobra filas examinadas, no filas devueltas. Una consulta sin índice que recorre 50.000 filas para devolverte 10 te cuenta como 50.000 lecturas. En D1 un índice bien puesto se nota en la factura, no solo en la latencia.

Desde el 1 de septiembre de 2026, el plan Free bloquea las consultas al pasar el límite diario. Lo anunció Cloudflare en su changelog: las queries fallan hasta que el contador se reinicia a medianoche UTC. Una query mal indexada te puede tumbar la aplicación hasta el día siguiente.

D1 tiene además replicación de lectura global, que se aprovecha con su Sessions API para mantener consistencia secuencial dentro de una sesión: las escrituras van a la primaria y las lecturas a la réplica cercana. Es interesante para una webapp con usuarios repartidos por el mundo, pero no la activaría hasta haber medido que la latencia de lectura es un problema.

¿Y si D1 se queda corto? Si necesitas PostgreSQL por obligación, extensiones concretas o más de 10 GB por base, Cloudflare tiene Hyperdrive, que gestiona y acelera las conexiones desde Workers a una base PostgreSQL o MySQL externa. Es la salida natural cuando D1 deja de encajar, no una pieza para el primer día.

KV: el almacén fácil de usar mal

Workers KV es un almacén clave-valor distribuido por toda la red. Su API es tan mínima (get, put, y poco más) que dan ganas de meterlo todo ahí. No lo hagas.

KV está optimizado para lecturas globales y es eventualmente consistente: una escritura puede tardar en ser visible desde otras ubicaciones. Para feature flags, configuración leída a menudo, contenido cacheado o respuestas precalculadas es perfecto. Para un saldo, un stock, un pago confirmado o un permiso que tiene que revocarse ya, es un bug esperando su momento.

Los precios te empujan en la misma dirección. En Paid, un millón de lecturas extra cuesta 0,50 dólares y un millón de escrituras, 5 dólares: escribir sale diez veces más caro que leer. KV está pensado para cargas de lectura, no para hacer de log de eventos.

R2: archivos con salida gratis

R2 es el almacenamiento de objetos de Cloudflare, compatible con buena parte del ecosistema S3. Aquí van PDFs, adjuntos, imágenes originales, exports y backups. La regla es sencilla: los metadatos estructurados van a D1 (quién subió el archivo, su tipo, su tamaño, su clave en R2) y el contenido binario, a R2.

La salida de datos (egress) es gratis, y eso cambia las cuentas frente a proveedores que te cobran cada descarga. El plan Standard cobra 0,015 dólares por GB y mes, más las operaciones, y el free tier mensual incluye 10 GB, un millón de operaciones de clase A y diez millones de clase B.

Para las subidas de los usuarios están las URLs prefirmadas. El Worker comprueba que el usuario tiene permiso, genera una URL temporal para subir un objeto concreto y el navegador sube el archivo directo a R2, sin que tu Worker tenga que transportar cada byte. Trátala como un token de acceso temporal: una operación concreta, un objeto concreto, caducidad corta y emitida solo después de autorizar al usuario.

Para las imágenes está Cloudflare Images, que redimensiona, recorta, cambia de formato y genera variantes a partir de los originales, incluidos los que guardas en R2. Incluye 5.000 transformaciones únicas al mes y después cobra 0,50 dólares por cada 1.000. Si dejas que el cliente pida width=1 hasta width=5000, cada tamaño cuenta como una transformación distinta. Define un puñado de variantes y no aceptes más.

Usuarios, login y protección contra bots

La autenticación vive en tu Worker y sus datos en D1, con una librería de autenticación auditada que funcione en el runtime de Workers. Delante pones Turnstile para filtrar bots y el binding de Rate Limiting para frenar abusos. Y Cloudflare Access queda para otra cosa: proteger tus paneles internos, no gestionar a tus clientes.

Esa confusión es la primera trampa del catálogo. Access es un proxy que se coloca delante de una aplicación y decide quién llega según la identidad, el proveedor de login o el estado del dispositivo. Es fantástico para admin.tudominio.com o staging.tudominio.com, porque proteges el panel sin escribir una línea de login. Pero no es la tabla de users, sessions, organizations y permisos de tu SaaS.

Tampoco escribirías tu propia criptografía por pureza Cloudflare. La infraestructura es de Cloudflare; el protocolo de autenticación, de una librería que alguien ha auditado.

Turnstile y Rate Limiting responden a preguntas distintas

Turnstile es la alternativa de Cloudflare al CAPTCHA. Funciona en dos fases: el navegador resuelve un desafío (casi siempre invisible) y obtiene un token, y tu backend valida ese token contra el endpoint Siteverify. Si no validas el token en el servidor, el widget es decoración. El plan gratuito permite hasta 20 widgets y desafíos ilimitados.

El binding de Rate Limiting te deja aplicar límites desde el código con la clave que quieras: IP, user_id, tenant, API key, ruta o plan. Puedes tener un límite de free:user:123:/ai y otro distinto para pro:user:456:/ai. La ventana solo puede ser de 10 o 60 segundos, y el contador se evalúa en local, así que apenas añade latencia.

La documentación avisa de su límite: el binding es «permisivo, eventualmente consistente, y está diseñado a propósito para no usarse como sistema de contabilidad exacto». Sirve para frenar abusos. Para créditos que se facturan, cuenta en D1.

💡 Turnstile responde a «¿esto parece una persona?». Rate Limiting responde a «¿está haciendo demasiadas cosas?». En un formulario público necesitas las dos respuestas.

Qué pasa cuando alguien se registra

El registro junta casi todo lo anterior y separa lo que el usuario tiene que esperar de lo que puede pasar después.

Dentro de la request el usuario está esperando Fuera de la request el usuario ya tiene su respuesta POST /signup Turnstile · valida el token con Siteverify Rate Limiting · frena ráfagas por IP D1 · crea el usuario y el token de verificación Queue · encola el email de verificación Analytics Engine · registra signup_created 201 Created Aquí va lo que puede esperar unos segundos: correo, webhooks, procesado de archivos Consumer de la Queue Email Service · envía el correo si el envío falla, la Queue reintenta el mensaje Si el correo tarda o falla, el registro ya está guardado y el usuario no lo nota

En código, una versión reducida del endpoint y de los otros dos handlers de ese mismo Worker quedaría así. Es código de referencia armado desde la documentación, no algo que yo tenga en producción, y deja fuera Turnstile y el hash de la contraseña para no alargarlo:

type Task = { type: "verify-email"; userId: string; email: string };

export default {
  async fetch(request, env): Promise<Response> {
    const url = new URL(request.url);

    if (url.pathname === "/api/signup" && request.method === "POST") {
      // Antiabuso barato: el contador se evalúa en local
      const ip = request.headers.get("CF-Connecting-IP") ?? "anon";
      const { success } = await env.SIGNUP_LIMIT.limit({ key: `signup:${ip}` });
      if (!success) return new Response("Demasiados intentos", { status: 429 });

      const { email } = await request.json<{ email: string }>();
      const userId = crypto.randomUUID();

      // D1 es la fuente de verdad
      await env.DB.prepare("INSERT INTO users (id, email) VALUES (?, ?)")
        .bind(userId, email)
        .run();

      // El correo sale de la request: se encola y se responde ya
      await env.TASKS.send({ type: "verify-email", userId, email });

      return Response.json({ id: userId }, { status: 201 });
    }

    return new Response("Not found", { status: 404 });
  },

  // Consumidor de la cola: aquí se llamaría a Email Service
  async queue(batch, env): Promise<void> {
    for (const msg of batch.messages) {
      // sendVerificationEmail(msg.body, env)
      msg.ack();
    }
  },

  // Cron diario: limpia sesiones caducadas
  async scheduled(controller, env): Promise<void> {
    await env.DB.prepare("DELETE FROM sessions WHERE expires_at < ?")
      .bind(Date.now())
      .run();
  },
} satisfies ExportedHandler<Env, Task>;

Tres handlers en el mismo archivo: fetch atiende HTTP, queue procesa los mensajes de la cola y scheduled se ejecuta con el cron. Es la misma aplicación con tres puertas de entrada.

Un apunte sobre el login: las sesiones van a D1, no a KV. Si un usuario cierra sesión o le quitas el acceso, quieres que deje de funcionar ya, no «cuando se propague».

Sacar trabajo de la request con Queues, Cron y Workflows

Sale de la request todo lo que el usuario no necesita ver terminado para recibir su respuesta: emails, webhooks, procesado de archivos, notificaciones. Queues transporta ese trabajo, Cron Triggers despierta al Worker a una hora fija y Workflows coordina procesos de varios pasos que pueden durar horas o días.

El correo es el ejemplo de manual. Email Service envía correo transaccional (verificación, magic links, recuperación de contraseña, invitaciones) y recibe correo con Email Routing. El envío sigue en beta en septiembre de 2026. Enviar a cualquier destinatario exige Workers Paid, incluye 3.000 emails al mes y cobra 0,35 dólares por cada 1.000 más. Recibir correo es ilimitado, y enviar a direcciones verificadas de tu propia cuenta es gratis en todos los planes.

No lo metería nunca como parte crítica de la request. El proveedor tarda, falla o limita, y el usuario no tiene por qué comerse esa espera.

Queues transporta trabajo Workflows recuerda en qué paso vas Cron Triggers pone la hora env.TASKS.send(msg) el mensaje espera en la cola queue() lo procesa msg.ack() · hecho ↻ si falla, reintenta el mensaje paso 1 · leer los datos de D1 paso 2 · guardar el export en R2 espera 7 días · sin gastar CPU paso 3 · borrar el export ↻ si falla, reintenta solo ese paso 0 3 * * * (UTC) scheduled() se ejecuta borra sesiones caducadas borra exports viejos de R2 ideal para tareas de un solo paso Ej.: el email de bienvenida Ej.: exportar una cuenta Ej.: la limpieza nocturna Si tu tarea periódica crece hasta tener pasos, esperas y reintentos, pásala a Workflows

Queues: cuando el trabajo solo tiene que hacerse

Queues es la pieza para el «haz esto, pero no ahora». Tu Worker envía un mensaje y responde; un consumidor lo procesa después y, si falla, la cola lo reintenta.

Se factura por operaciones, y cada bloque de hasta 64 KB escrito, leído o borrado cuenta como una. Un mensaje procesado sin problemas suele suponer al menos tres: escribirlo, leerlo y confirmarlo. Un mensaje no equivale a una operación. El plan Free da 10.000 operaciones al día y el Paid incluye un millón al mes, con 0,40 dólares por millón adicional y sin cargos por egress ni por throughput.

Cron Triggers: cuando solo necesitas un despertador

Cron Triggers ejecuta tu Worker según una expresión cron. Sirve para limpiar tokens caducados, generar un resumen diario o recalcular estadísticas. No se cobra como producto aparte: cada ejecución es una invocación normal de Workers.

Los horarios se interpretan en UTC, así que tu «a las 3 de la mañana» probablemente no es tu hora local. Y el límite de CPU depende del intervalo: con un cron que se ejecuta cada hora o menos a menudo tienes hasta 15 minutos de CPU, pero con intervalos más cortos el límite baja a 30 segundos. La guía original de la IA daba los 15 minutos para todos los casos, y no es así. El plan Free permite 5 Cron Triggers por cuenta y el Paid, 250.

Workflows: cuando el trabajo es un proceso

Workflows entra cuando una tarea deja de ser un «haz esto» y se convierte en «haz A, espera, haz B, reintenta si falla, espera un evento, haz C». El ejemplo clásico es exportar la cuenta de un usuario: leer sus datos de D1, enumerar sus archivos en R2, generar el paquete, guardarlo en R2, mandarle un enlace temporal por email, esperar siete días y borrar el export.

Montar eso con requests y crons es posible, pero te obliga a construir tu propia máquina de estados con tablas de «en qué paso va cada export». Workflows guarda ese estado por ti, reintenta solo el paso que falla y las esperas no consumen CPU mientras duermen.

El plan Free incluye 3.000 pasos al día; el Paid, 500.000 al mes y 0,80 dólares por cada 100.000 más, aparte del almacenamiento de estado y de las requests y la CPU de Workers. La facturación de pasos y almacenamiento empezó el 10 de agosto de 2026, así que muchos artículos anteriores lo presentan como gratis.

🔑 Queue transporta trabajo. Workflow recuerda en qué paso de un proceso estás. Para mandar un email, Workflow es matar moscas a cañonazos.

¿Cuándo hace falta un Durable Object?

Cuando varios usuarios tienen que coordinarse alrededor de la misma cosa en tiempo real: una sala de chat, un documento colaborativo, un quiz en directo, una partida. Un Durable Object es un objeto con identidad global que actúa como punto único de coordinación para una entidad. Todas las operaciones sobre room:123 van al mismo objeto, y eso elimina las carreras entre peticiones que llegan a la vez.

Para mí es el concepto más raro de Cloudflare, y no conviene pensarlo como «otra base de datos». Si quieres entender el modelo desde fuera de Cloudflare, en el post sobre celld está explicado con el caso de ejecutarlo en tus propias máquinas.

La diferencia con D1 se ve bien con un quiz en directo:

Qué Dónde
Las sesiones, preguntas y resultados guardados D1
Quién está conectado ahora mismo Durable Object quiz:123
La pregunta que se está mostrando Durable Object quiz:123
El contador de respuestas en vivo Durable Object quiz:123
El broadcast por WebSocket a todos los jugadores Durable Object quiz:123

Un Durable Object puede mantener miles de conexiones WebSocket por instancia. El coste tiene trampa. Un objeto que mantiene WebSockets abiertos sin hacer nada puede seguir activo y facturando duración. Cloudflare recomienda la WebSocket Hibernation API, que deja al objeto hibernar cuando no hay actividad sin cerrar las conexiones, «para evitar cargos de duración».

⚠️ La hibernación de WebSockets no es una optimización para más adelante. Si tu Durable Object usa WebSockets, va en el diseño desde el primer día.

Los números: en Free, 100.000 requests y 13.000 GB-s al día. En Paid, un millón de requests al mes (0,15 dólares por millón extra) y 400.000 GB-s (12,50 dólares por millón de GB-s extra). El almacenamiento SQLite de los Durable Objects se cobra en línea con D1.

Lo que no haría es usar Durable Objects para un CRUD normal. No necesitas un coordinador global por cada fila de tu tabla de proyectos.

Observabilidad: logs, trazas y eventos de producto

La observabilidad se reparte entre tres piezas que no se pisan: Analytics Engine para eventos de producto, Workers Logs para lo que pasó en cada ejecución y Workers Traces para saber dónde se fue el tiempo de una request que atraviesa varios servicios.

En cuanto el registro de usuario pasa por un Worker, D1, una cola, un consumidor y un servicio de correo, «no me llega el email de verificación» puede ser un fallo en cinco sitios distintos. Sin observabilidad, lo depuras a base de console.log y fe.

Analytics Engine guarda eventos de alta cardinalidad y deja consultarlos con SQL. La diferencia con D1 es conceptual: D1 guarda estado («el usuario 123 tiene plan pro») y Analytics Engine guarda eventos («el usuario 123 usó la feature X», «recibió un 429», «el modelo gastó N tokens»). Sirve para medir uso por usuario, cuotas blandas, errores por endpoint o coste aproximado por cliente. Tiene precios publicados (en Paid, 10 millones de datapoints y un millón de consultas incluidos al mes), pero a día de hoy su página de precios dice que todavía no se factura su uso.

Workers Logs recoge invocaciones, console.log, errores y excepciones. En Free son 200.000 eventos al día con 3 días de retención; en Paid, 20 millones al mes con 7 días y 0,60 dólares por millón extra. Si cada request escribe veinte líneas de log, esos 20 millones se van rápido. Logs estructurados y muestreo desde el principio.

Workers Traces sigue una request por los servicios que toca (fetch, KV, R2, Durable Objects) y te dice si la lentitud estaba en tu código, en D1 o en una API externa. Es gratis mientras dura su beta, pero desde el 1 de octubre de 2026 se factura con el mismo modelo que los logs, y cada span cuenta como un evento. Si activas trazas en todo, cuenta con ello.

Del mapa al despliegue real

Lo que pasa cuando una webapp hecha con IA llega a producción

Te llevas el flujo de trabajo real con agentes para construir y desplegar una webapp entera, por qué desplegar pronto salva el proyecto y el fallo en producción que acabó duplicando suscripciones en Stripe.

Ver el caso real →

Audio premium · Web Reactiva Premium

¿Cómo añado IA sin que el abuso acabe en la factura?

Con Workers AI para ejecutar el modelo, AI Gateway delante para observar, cachear y limitar, y toda la cadena de protección de antes aplicada a la ruta de IA. Un endpoint público de IA sin límites es una invitación a que alguien convierta tu factura en su chatbot gratis.

Workers AI ejecuta modelos en la infraestructura de Cloudflare a través de un binding, así que el navegador nunca ve ninguna credencial. Se mide en Neurons: 10.000 al día gratis en cualquier plan y 0,011 dólares por cada 1.000 a partir de ahí en Paid. Algunos modelos grandes exigen el plan Paid (o créditos prepago de AI Gateway) aunque te queden Neurons gratuitas.

Para aprender la infraestructura no hace falta construir una «aplicación de IA». Basta con una función acotada: resumir un texto del usuario, clasificar contenido, generar etiquetas o sugerir un título.

AI Gateway se coloca delante de los modelos, sean de Workers AI o de proveedores externos. Sus funciones básicas (analítica, caché y rate limiting) son gratuitas. Si pagas varios proveedores a través de su facturación unificada, Cloudflare no añade margen al precio de inferencia pero cobra un 5% sobre los créditos que compras. Desde agosto de 2026 Workers AI y AI Gateway comparten binding y esos créditos también pagan la inferencia de Workers AI.

La cadena para una feature pública quedaría así:

  1. Turnstile para filtrar bots
  2. Autenticación para saber quién pide
  3. Rate Limiting para frenar ráfagas
  4. Cuota de producto en D1 para lo que se factura de verdad
  5. AI Gateway para observar, cachear y limitar
  6. Workers AI para ejecutar el modelo

¿Y Vectorize? Es la base de datos vectorial de Cloudflare, para búsqueda semántica, recomendaciones o RAG. La metería solo el día que aparezca un caso real de similitud semántica. Si un LIKE, una búsqueda de texto completo o unos filtros SQL resuelven el problema, D1 es más sencillo. Vectorize es para cuando necesitas similitud, no para cuando necesitas buscar.

Las cuotas gratis y los precios de la inferencia cambian cada pocas semanas. Cada domingo, +7.200 developers comparten en la newsletter lo que van probando con IA para poner orden en ese cambio. Gratis, desde 2018.

Suscríbete gratis →

Lo que cuesta de verdad con el plan de 5 dólares

Para una aplicación pequeña, el plan Workers Paid de 5 dólares al mes puede ser la factura base de casi todo el stack, porque muchos productos incluyen cuotas generosas dentro de ese plan antes de cobrar excesos. Pero Cloudflare cobra por uso en casi todo, así que 5 dólares es un suelo, no una tarifa plana.

La foto a 18 de septiembre de 2026:

Servicio Free Incluido en Paid y exceso
Workers 100.000 req/día, 10 ms CPU 10 M req + 30 M CPU-ms al mes; $0,30/M req, $0,02/M CPU-ms
Static Assets Gratis e ilimitado Gratis e ilimitado
D1 5 M filas leídas y 100.000 escritas al día, 5 GB 25.000 M leídas y 50 M escritas al mes; $0,001/M y $1/M
R2 10 GB-mes, egress gratis $0,015/GB-mes, egress gratis
KV 100.000 lecturas y 1.000 escrituras al día 10 M lecturas + $0,50/M; 1 M escrituras + $5/M
Queues 10.000 operaciones al día 1 M al mes + $0,40/M
Email Service Solo a direcciones verificadas 3.000 emails al mes + $0,35 por 1.000
Workflows 3.000 pasos al día 500.000 al mes + $0,80 por 100.000
Durable Objects 100.000 req y 13.000 GB-s al día 1 M req + $0,15/M; 400.000 GB-s + $12,50/M
Images 5.000 transformaciones únicas al mes $0,50 por 1.000
Workers Logs 200.000 eventos al día, 3 días 20 M al mes, 7 días, + $0,60/M
Workers AI 10.000 Neurons al día $0,011 por 1.000 Neurons
Turnstile Gratis, 20 widgets Enterprise bajo presupuesto

La pregunta que merece la pena comprobar con un proyecto real es cuánta aplicación se puede construir antes de que la factura supere con claridad esos 5 dólares.

Yo no tengo la respuesta todavía. Lo que sí tengo es la lista de sitios por donde se escapa el dinero:

  • Durable Objects sin hibernación: facturan duración aunque no hagan nada.
  • Workers AI en una ruta pública: sin límites, el abuso es tu factura.
  • Logs sin control: veinte líneas por request agotan los 20 millones incluidos.
  • Escrituras en KV: cuestan diez veces más que las lecturas.
  • Operaciones de R2: el egress es gratis, pero las operaciones y el almacenamiento no.
  • Variantes arbitrarias de Images: cada tamaño distinto es una transformación única.
  • Workflows con pasos de más: cada paso cuenta, no conviertas una función trivial en cien.

El orden en el que aprendería cada pieza

Lo aprendería por fases, cada una con un resultado visible. Implementar la arquitectura completa en un sprint es la mejor manera de no entender ninguna pieza.

  1. Edge y runtime. DNS, proxy, Universal SSL, Workers, Static Assets, Wrangler, bindings, secretos y logs. Resultado: la web desplegada entera en Cloudflare.
  2. Usuarios. D1, sesiones, Turnstile, Rate Limiting y Email Service. Resultado: registro, login, verificación de email y recuperación de contraseña.
  3. Contenido de usuarios. R2, URLs prefirmadas, Images y metadatos en D1. Resultado: avatares, archivos privados y miniaturas.
  4. Trabajo asíncrono. Queues, consumidores y Cron Triggers. Resultado: emails, webhooks y procesados secundarios fuera de la request.
  5. Procesos. Workflows, en cuanto aparezca uno real de varios pasos, como la exportación de cuenta.
  6. Tiempo real. Durable Objects y WebSockets para una sola funcionalidad concreta, por ejemplo la presencia en una sesión compartida.
  7. Analítica de producto. Analytics Engine para uso por feature, rate limits, latencias de negocio y errores por operación.
  8. IA. Workers AI, AI Gateway, límites y telemetría. Vectorize solo si aparece búsqueda semántica.

Y fuera de la lista, a propósito: Stream sin vídeo, Hyperdrive si D1 encaja, Access como login de clientes o KV para datos que caben de forma natural en D1. Cloudflare-first no es Cloudflare a cualquier precio.

Errores de diseño que evitaría desde el principio

Casi todos salen de usar un producto para lo que parece que hace en lugar de para lo que hace de verdad. Esta es la matriz que tendría abierta mientras diseño:

Necesidad Primera opción Evitar
Datos con relaciones D1 KV
Archivos R2 Blobs grandes en D1
Config global de solo lectura KV D1 si solo necesitas clave-valor
Consistencia inmediata D1 o Durable Object KV
Antiabuso por usuario o ruta Rate Limiting Contadores exactos en KV
Créditos que se facturan D1 Rate Limiting
Trabajo en segundo plano Queues Alargar la request
Tarea periódica simple Cron Trigger Un Workflow innecesario
Proceso de varios pasos Workflows Crons encadenados y tablas de estado
Coordinación en tiempo real Durable Objects Polling y locks caseros
Eventos de producto Analytics Engine Llenar D1 de logs
Subidas grandes URLs prefirmadas de R2 Pasar cada byte por el Worker
Backoffice privado Access Confundirlo con el login de clientes

El criterio de fondo sigue siendo el de Flavio: empezar por el problema y usar la pieza más pequeña que lo elimine. La diferencia es que aquí, cuando Cloudflare tiene una solución razonable, se prueba antes de salir de la plataforma, para ver con tus propios ojos dónde encaja, qué simplifica, qué limita y cuánto cuesta.

La métrica de aprendizaje que me pongo es poder explicar cada producto no por su página comercial, sino por el momento exacto en que la aplicación lo necesitó.

¿Te animas a abrir una cuenta y empezar por la fase 1 este finde?

TL;DR

  • 🧩 En Cloudflare todo gira alrededor del Worker: los servicios se enchufan con bindings y aparecen en tu código como variables de env, sin URLs ni credenciales.
  • 🚦 No toda request debería ejecutar código: los Static Assets y la caché responden desde el edge gratis, y solo cuentan como Workers las requests que llegan a tu código.
  • 🗄️ D1 para datos relacionales, R2 para archivos (con egress gratis), KV solo para lo que se lee mucho y tolera retraso, y nunca saldos ni permisos en KV.
  • Queues transporta trabajo, Workflows recuerda en qué paso vas y Cron pone la hora; los emails y webhooks van siempre fuera de la request.
  • 💸 Con Workers Paid a 5 dólares al mes cubres la base de casi todo el stack, pero Durable Objects sin hibernación, IA pública sin límites y logs sin control son los agujeros de la factura.

Preguntas frecuentes sobre crear una webapp en Cloudflare

¿Se puede alojar una aplicación web completa en Cloudflare sin servidor propio?
Sí. Workers ejecuta el backend, Static Assets sirve el frontend, D1 guarda los datos relacionales y R2 los archivos. Queues, Workflows, Email Service y Durable Objects cubren el trabajo asíncrono, el correo y el tiempo real sin salir de la plataforma.

¿Workers o Pages para un proyecto nuevo en 2026?
Workers con Static Assets. La documentación de buenas prácticas de Cloudflare recomienda Workers para proyectos nuevos y dice que las nuevas funcionalidades se concentran ahí. Pages sigue funcionando y no está deprecado, así que los proyectos existentes pueden seguir en él.

¿Qué es un binding en Cloudflare Workers?
Es la conexión entre un Worker y un recurso de la plataforma, como una base D1, un bucket R2 o una cola. Se declara en wrangler.jsonc y en el código aparece como una propiedad de env, sin URLs ni credenciales. Cloudflare los recomienda frente a sus APIs REST dentro de la plataforma.

¿Cuánto cuesta Cloudflare Workers?
El plan Free incluye 100.000 requests al día y 10 ms de CPU por invocación. El plan Paid cuesta 5 dólares al mes e incluye 10 millones de requests y 30 millones de milisegundos de CPU mensuales, con 0,30 dólares por millón de requests extra y 0,02 dólares por millón de CPU-ms extra. No se cobra el tiempo de espera, solo la CPU.

¿Cuál es la diferencia entre D1 y KV?
D1 es una base de datos SQL sobre SQLite para datos con relaciones, filtros e índices, y es la fuente de verdad de la aplicación. KV es un almacén clave-valor global y eventualmente consistente, pensado para lecturas frecuentes de configuración o caché. Saldos, stock o permisos que se revocan al instante nunca van a KV.

¿Qué pasa si supero el límite gratuito de D1?
Desde el 1 de septiembre de 2026, las consultas del plan Free fallan al superar el límite diario hasta que se reinicia a medianoche UTC. Como D1 cuenta las filas examinadas y no las devueltas, una consulta sin índice puede agotar el cupo mucho antes de lo que esperas.

¿Cómo se suben archivos a R2 sin pasar por el Worker?
Con URLs prefirmadas. El Worker comprueba que el usuario tiene permiso y genera una URL temporal para una operación y un objeto concretos, y el navegador sube el archivo directo a R2. Los metadatos del archivo se guardan después en D1.

¿Cloudflare Access sirve como sistema de login para mis usuarios?
No. Access es un proxy con control de identidad para proteger aplicaciones internas como paneles de administración o entornos de staging. El login de los clientes de tu producto vive en tu Worker, con una librería de autenticación auditada y los datos en D1.

¿Cuál es la diferencia entre Queues y Workflows?
Queues transporta trabajo de un solo paso, como enviar un email, y reintenta el mensaje si falla. Workflows coordina procesos de varios pasos con estado, puede esperar horas o días sin consumir CPU y reintenta solo el paso que falla. Para una tarea periódica sencilla basta un Cron Trigger.

¿Cuándo necesito un Durable Object?
Cuando varios usuarios tienen que coordinarse sobre la misma entidad en tiempo real: salas de chat, documentos colaborativos, quizzes en directo o juegos. Si usa WebSockets, aplica la WebSocket Hibernation API desde el principio para no pagar duración mientras el objeto no hace nada.

Fuentes

La inspiración para esta guía llegó de la mano de Flavio Copes y su artículo The Cloudflare products I actually use. Si quieres ver cómo usa Cloudflare alguien que sí lo tiene en producción, empieza por ahí.

🧨 Última oprtunidad para recibir la dinamita que mereces sobre programación con IA el próximo domingo: Suscríbete gratis a Web Reactiva en https://webreactiva.com/newsletter

Imagen de Daniel Primo
Claude, IA de Anthropic

Escrito con la ayuda de la IA generativa de Claude, fuentes fidedignas y con un human in the loop:
Dani Primo.

CEO en pantuflas de Web Reactiva. Programador y formador en tecnologías que cambian el mundo y a las personas. Activo en linkedin, en substack y canal @webreactiva en telegram

12 recursos para developers cada domingo en tu bandeja de entrada

Además de una skill práctica bien explicada, trucos para mejorar tu futuro profesional y una pizquita de humor útil para el resto de la semana. Gratis.