wandres.dev
NIVEL DIOS: SÍNTESIS · la plataforma completa

Cloudflare frente a AWS, Vercel y Fly: la comparación honesta

Un track entero sobre una plataforma corre el riesgo de convertirse en publicidad. Esta lección hace lo contrario: compara el modelo de Cloudflare con AWS, Vercel y Fly sin adornos. Cuatro apuestas distintas sobre dónde debe correr el cómputo, cuatro modelos de coste que se miden en unidades incomparables, cuatro grados de madurez muy desiguales y cuatro formas de lock-in que se pagan en momentos distintos. Y la parte que casi nadie escribe: los casos concretos en los que elegir Cloudflare es la decisión equivocada.

⏱ 25 min

Después de treinta niveles defendiendo un modelo, toca someterlo a examen. Cloudflare no es una plataforma mejor que las demás: es una plataforma que hizo apuestas distintas, y esas apuestas tienen ganancias reales y pérdidas reales que casi nunca aparecen juntas en la misma página. Esta lección pone las cuatro grandes opciones sobre la mesa —Cloudflare, AWS, Vercel y Fly— y las compara en los cuatro planos que de verdad deciden: el modelo de ejecución, el coste, la madurez del ecosistema y la forma del lock-in. Terminarás sabiendo defender la elección y, más importante, sabiendo cuándo no defenderla.

🎯 Al terminar esta lección sabrás
  • Distinguir las cuatro apuestas de ejecución y qué problema resuelve cada una.
  • Comparar modelos de coste que se facturan en unidades distintas sin caer en falsas equivalencias.
  • Evaluar la madurez real de cada ecosistema y qué falta todavía en el edge.
  • Reconocer los casos concretos en los que Cloudflare es la elección equivocada.

Cuatro apuestas sobre dónde debe correr el cómputo

Antes de comparar nada conviene fijar el criterio, porque la mayoría de las comparativas de plataformas fallan en el mismo punto: contrastan características en lugar de contrastar apuestas. Una característica se copia en un trimestre y por eso no distingue a nadie a largo plazo; una apuesta es una decisión estructural sobre dónde debe correr el cómputo, y condiciona lo que la plataforma podrá y no podrá hacer durante años. Las cuatro que siguen se distinguen por sus apuestas, no por sus listas.

AWS apostó por la generalidad. Su tesis es que cualquier cosa que quieras hacer debe ser posible, aunque el camino sea largo, y el resultado es un catálogo de doscientos servicios donde existe una respuesta a todo: máquinas virtuales, contenedores, funciones, bases relacionales gestionadas, colas, streaming, aprendizaje automático, redes privadas y treinta formas de conectar todo eso. El precio de esa generalidad es la complejidad operativa. Montar una aplicación seria en AWS implica decidir VPC, subredes, grupos de seguridad, roles de IAM, políticas y un despliegue declarativo que hay que mantener; y ese trabajo, que no produce funcionalidad, es real y recurrente.

Vercel apostó por la experiencia del desarrollador de front-end. Su tesis es que el despliegue debe desaparecer como problema, y lo cumple mejor que nadie: empujas a una rama y hay una vista previa funcionando con su URL. Está construida encima de infraestructura de otros, integrada de forma estrecha con Next.js, y su valor está en la capa de producto, no en la de sistemas. La contrapartida es que fuera de ese carril te quedas sin gran cosa: no hay almacenamiento propio con la profundidad de un catálogo, no hay un modelo de estado coordinado y todo lo que no es render acaba siendo un servicio de terceros que tú integras.

Esa diferencia entre Vercel y Cloudflare se ve mejor preguntando dónde está el producto de cada una. En Vercel el producto es la capa de despliegue y previsualización, y el cómputo es un medio para sostenerla. En Cloudflare el producto es la red y lo que corre en ella, y las herramientas de despliegue existen para alcanzarla. Ninguna de las dos posiciones es superior en abstracto; lo que decide es si tu problema principal es entregar interfaces rápido o construir un sistema con estado, y confundir cuál de los dos es el tuyo produce elecciones que se lamentan a los seis meses.

Fly apostó por lo contrario que Cloudflare dentro del mismo objetivo. Quiere latencia baja global, pero llega a ella distribuyendo máquinas de verdad en muchas regiones en vez de isolates en cientos de puntos de presencia. Corres tu Dockerfile, con tu Postgres, tus procesos largos, tus binarios nativos y tus dependencias de sistema. Es la opción más pragmática para quien tiene una aplicación que ya existe y quiere acercarla al usuario sin reescribirla: no cambias el modelo de programación, cambias el mapa.

El precio de esa comodidad es que las regiones vuelven a ser tuyas. Decides cuántas máquinas hay y dónde, cómo replicas la base entre ellas, qué pasa cuando una región se cae y cómo enrutar la escritura a la primaria desde una réplica lejana. Son problemas conocidos y resolubles, pero son problemas, y su coste no aparece en la factura sino en el calendario del equipo. Cloudflare los hace desaparecer a cambio de que no puedas ejecutar tu Dockerfile; Fly te deja ejecutarlo a cambio de que la geografía siga siendo tu responsabilidad. Formulada así, la elección deja de ser ideológica y se vuelve un cálculo bastante concreto.

Cloudflare apostó por el isolate. Su tesis es que si renuncias a ejecutar cualquier binario y aceptas un entorno de JavaScript con APIs web estándar, se pueden desplegar cientos de miles de aplicaciones por máquina, arrancar en cero milisegundos y estar en todas partes a la vez sin aprovisionar nada. Es la apuesta más radical y la que impone una restricción real, pero es también la que da propiedades que las otras tres no pueden dar: sin cold start, sin regiones, sin escalado que configurar, y con un almacenamiento diseñado desde cero para vivir en ese mismo mundo.

La consecuencia de esas cuatro apuestas que menos se comenta es lo que cada una hace con el cold start, porque no es un detalle de rendimiento sino un condicionante de arquitectura. En un modelo de funciones, el arranque en frío empuja a hacer las funciones grandes —para que se invoquen a menudo y se mantengan calientes— y castiga la descomposición en servicios pequeños. En el modelo de isolates ese incentivo desaparece: descomponer no cuesta nada, y por eso un sistema en Workers tiende naturalmente a varios servicios pequeños unidos por bindings, mientras que el mismo sistema en Lambda tiende a un monolito de funciones gordas. La plataforma no solo cambia dónde corre tu código: cambia la forma que tu código quiere tener.

flowchart TD
A[donde corre el codigo] --> B[maquina virtual o contenedor]
A --> C[funcion efimera]
A --> D[isolate]
B --> B1[AWS EC2 y ECS y Fly Machines]
B --> B2[cualquier binario y procesos largos]
C --> C1[AWS Lambda y funciones de Vercel]
C --> C2[escala a cero con arranque en frio]
D --> D1[Cloudflare Workers]
D --> D2[arranque cero y presencia global]
D --> D3[precio a pagar es el entorno restringido]

El coste: unidades que no se pueden comparar

Comparar precios entre plataformas es donde más se miente, casi siempre sin querer, porque cada una factura en una unidad distinta y las unidades no se convierten unas en otras. AWS Lambda cobra por gigabyte y segundo de ejecución, y esa métrica incluye el tiempo que tu función pasa esperando una respuesta de red: si tu código hace una consulta que tarda doscientos milisegundos, pagas esos doscientos milisegundos aunque tu proceso estuviera dormido. Cloudflare cobra por petición y por tiempo de CPU, no de reloj: esperar es gratis. En una carga típica de aplicación web, donde la mayor parte del tiempo se va en esperar a bases de datos y a otras APIs, esa diferencia no es un matiz, es un factor grande.

Esa distinción entre reloj y CPU tiene un efecto de segundo orden que casi nunca se menciona: cambia qué optimizaciones tienen sentido. En un modelo que factura reloj, paralelizar consultas reduce la factura porque reduce el tiempo total; en uno que factura CPU, paralelizar no cambia el coste en absoluto, porque la espera era gratis desde el principio, y solo mejora la latencia. La consecuencia práctica es que los consejos de optimización de una plataforma no se trasladan a la otra, y que buena parte del folclore de rendimiento heredado del mundo de las funciones es, aquí, esfuerzo dirigido a un término que no se cobra.

La segunda diferencia estructural es el tráfico de salida. En las nubes clásicas, sacar datos hacia internet se factura por gigabyte y es una de las líneas más caras y menos predecibles de la factura. R2 no cobra salida, y esa decisión no es un descuento comercial sino un ataque deliberado al mecanismo por el que las nubes retienen a sus clientes: si mover tus datos fuera cuesta dinero, cada terabyte almacenado es un grillete adicional. La consecuencia práctica es que las cargas que sirven muchos bytes —medios, ficheros, copias, conjuntos de datos— tienen en Cloudflare una economía radicalmente distinta.

La tercera es el coste de la ociosidad. Fly y las bases gestionadas de AWS cobran por capacidad reservada: la máquina y la instancia de Postgres cuestan lo mismo a las cuatro de la madrugada que en hora punta. Los Workers, KV, R2 y D1 no reservan nada. Para un producto con tráfico irregular o con muchos entornos de prueba, esa diferencia domina la factura entera, y en el otro extremo —tráfico constante y previsible las veinticuatro horas— la capacidad reservada puede salir más barata.

// La comparacion honesta no es por hora de computo, es por peticion completa.
const enModeloDeReloj = (msEspera + msCpu) * gbAsignados * precioGbSegundo;
const enModeloDeCpu = precioPorPeticion + msCpu * precioPorMsCpu;
// Con msEspera = 180 y msCpu = 4, el primer modelo factura la espera 45 veces mas cara.

Hay una cuarta diferencia que rara vez entra en las comparativas y que en la práctica pesa mucho: el coste de los entornos que no son producción. Un equipo con quince ramas abiertas necesita quince vistas previas, y en un modelo de capacidad reservada cada una es una instancia encendida; en un modelo sin aprovisionamiento, quince entornos que nadie visita cuestan prácticamente cero. Esa asimetría no cambia la factura de producción, pero sí cambia la cultura de desarrollo, porque hace viable que cada cambio se pruebe en un entorno real en lugar de en una aproximación local.

Plano Cloudflare AWS Vercel Fly
Unidad de cobro Petición y CPU GB-segundo de reloj Petición y ancho de banda Capacidad reservada
Tráfico de salida Sin coste en R2 Caro por GB Caro por GB Moderado
Coste en reposo Cero Cero en Lambda, alto en RDS Bajo Proporcional
Escalado Automático e invisible Configurable y complejo Automático Manual por región
⚠️
El coste de la plataforma casi nunca es el coste real

La factura de infraestructura de un equipo pequeño suele ser un orden de magnitud menor que su nómina, y sin embargo consume una parte desproporcionada de la deliberación. El coste que de verdad decide un proyecto es el tiempo de ingeniería: cuántas semanas se van en montar y mantener lo que no es producto. Ahí Cloudflare y Vercel ganan claramente a AWS para equipos pequeños, y AWS gana cuando el equipo es grande, ya tiene esa infraestructura montada y la complejidad se amortiza entre muchos proyectos. Comparar precios por hora de cómputo ignorando ese término es optimizar la variable menor.

Madurez y lock-in: dos precios que se pagan en momentos distintos

La honestidad exige decirlo claro: el ecosistema del edge sigue siendo más joven. En AWS, cualquier problema que tengas ya lo tuvo alguien y hay una respuesta escrita en 2019 que sigue siendo válida. En Workers, hay áreas —bibliotecas que asumen APIs de Node, herramientas de perfilado, integraciones empresariales, controladores de bases de datos exóticas— donde la respuesta es que aún no existe o que hay que resolverlo de otra manera. nodejs_compat ha cerrado buena parte de esa brecha y sigue cerrándola, pero quien afirme que la paridad es total no ha migrado nada grande.

Conviene distinguir dos tipos de madurez que se confunden constantemente. La madurez del runtime es alta: Workers lleva años ejecutando una fracción enorme del tráfico mundial y su fiabilidad no está en discusión. La madurez del ecosistema alrededor —bibliotecas, integraciones, herramientas de terceros, respuestas en foros, gente contratable con experiencia— es claramente menor que la de AWS y en algunas áreas menor que la de Vercel. Confundir ambas lleva a dos errores simétricos: descartar la plataforma por inmadura cuando el runtime no lo es, o adoptarla sin presupuestar el tiempo que se irá en resolver cosas que en otro sitio ya estaban resueltas.

El lock-in merece un análisis menos perezoso que el habitual. Existe en las cuatro plataformas, pero se paga en momentos distintos y con formas distintas. En AWS es operativo: tu código suele ser portable, pero tu infraestructura declarativa, tus roles y tus integraciones son un trabajo de meses que no se muda. En Vercel es de framework: si construiste sobre las convenciones profundas de Next.js, moverte implica reescribir la capa de render. En Fly es el más leve de todos, porque un contenedor es un contenedor y corre en cualquier sitio. En Cloudflare es de API: tu lógica de negocio es JavaScript estándar y viaja bien, pero env.KV.get, un DurableObjectNamespace o un binding de servicio no tienen equivalente fuera, y eso es precisamente porque no existe nada equivalente fuera.

Ese último punto merece subrayarse, porque la conversación sobre lock-in suele confundir dos cosas muy distintas. Hay dependencias que atas sin ganar nada —una cola propietaria que hace lo mismo que cualquier otra— y dependencias que atas porque compras una capacidad que no se puede replicar. Un Durable Object pertenece a la segunda categoría: no hay forma de emularlo con Lambda y DynamoDB sin reconstruir a mano la serialización, la persistencia colocada y la migración de la entidad, que es exactamente el trabajo difícil. Aceptar esa dependencia es una decisión defendible; aceptarla sin saber que la has aceptado no lo es.

La técnica que reduce el lock-in a un coste manejable no es evitar las APIs propietarias, que sería renunciar a la plataforma, sino mantener el dominio ignorante de dónde vive. Si tus reglas de negocio son funciones que reciben datos y devuelven decisiones, y los bindings solo aparecen en una capa fina que las alimenta, migrar consiste en reescribir esa capa. Si en cambio la lógica está dentro de los handlers, mezclada con env y con detalles del transporte, estás atado no a Cloudflare sino a la forma concreta en que escribiste el código, y esa atadura te seguiría a cualquier destino.

// El dominio no sabe donde vive: recibe datos y devuelve decisiones.
export function puedeReservar(stock: number, pedido: number, plan: Plan): Decision {
  if (pedido > stock) return { ok: false, motivo: "sin stock" };
  if (plan === "free" && pedido > 3) return { ok: false, motivo: "limite del plan" };
  return { ok: true, restante: stock - pedido };
}
// La capa fina que lo alimenta es la unica que conoce los bindings, y es la unica que migra.
💡
Mide el lock-in por el coste de salir, no por el número de APIs propietarias

La pregunta útil no es cuántas APIs específicas usas, sino cuántas semanas costaría llevar este sistema a otra plataforma y qué parte de ese coste es lógica de negocio. Si tu dominio está en funciones puras y los bindings solo aparecen en una capa fina de acceso, el lock-in es una tarde de adaptadores por mucho que tu wrangler.jsonc esté lleno. Si has esparcido env por toda la base de código y tu lógica vive dentro de los handlers, estás atado a cualquier plataforma, incluida la que ya usas.

Cuándo Cloudflare es la elección equivocada

Hay casos donde la respuesta honesta es que no, y enumerarlos con precisión es más útil que cualquier defensa entusiasta de la plataforma, porque un criterio que nunca dice que no tampoco dice nada cuando dice que sí.

Cargas de CPU intensiva y sostenida —transcodificar vídeo, entrenar modelos, procesar imágenes grandes en lote, compilar— chocan con el límite de CPU por invocación, y aunque los Containers abren esa puerta, si ese trabajo es el núcleo de tu producto y no un caso lateral, estás pagando la restricción del isolate sin cobrar su ventaja.

Dependencias nativas y binarios son la segunda frontera. Un motor de bases de datos embebido, una biblioteca científica compilada, herramientas de sistema, procesos que necesitan un sistema de ficheros real. WebAssembly cubre una parte y los Containers otra, pero si tu aplicación se define por esas dependencias, Fly resuelve el problema sin fricción y sin adaptaciones.

Merece añadirse una tercera frontera menos evidente: el trabajo intensivo en datos que ya vive junto a los datos. Un proceso analítico que recorre cien millones de filas no debe salir de donde están esas filas, y ningún modelo de ejecución distribuida arregla el hecho de que mover los datos hasta el cómputo cuesta más que mover el cómputo hasta los datos. Si el núcleo de tu producto es ese tipo de carga, el edge no es el sitio equivocado por sus límites, sino porque el trabajo pertenece a otro plano de la aritmética que vimos en la primera lección.

Procesos de larga duración que mantienen estado en memoria durante horas —un servidor de juego, un demonio de sincronización, una conexión persistente a un sistema externo— encajan mal en un modelo donde la unidad de ejecución es la petición, aunque los Durable Objects y los Workflows cubren muchos de sus casos con una forma distinta de pensarlos. La pregunta que discrimina es si ese proceso necesita memoria continua o solo estado recuperable: lo segundo encaja perfectamente y lo primero no, y la mayoría de las veces que alguien cree necesitar lo primero, en realidad necesita lo segundo y le resulta incómodo reescribirlo.

Y está el caso menos técnico y más determinante: el equipo y el sistema que ya tienes. Si hay una plataforma AWS montada, con su cumplimiento normativo aprobado, sus auditorías pasadas, su equipo de operaciones y veinte servicios en producción, migrar al edge es un proyecto enorme cuyo beneficio hay que justificar con números. Lo razonable ahí no es migrar, es poner Cloudflare delante: caché, seguridad, un Worker que resuelve lo que se puede resolver cerca del usuario y Hyperdrive acelerando el acceso a lo que se queda donde está.

Ese patrón híbrido merece más respeto del que suele recibir, porque en la práctica es la forma en que la mayoría de las organizaciones grandes adoptan esta plataforma, y no es una versión descafeinada de nada. El Worker de borde absorbe autenticación, limitación de ritmo, pruebas A/B, reescritura de cabeceras, caché y las rutas de solo lectura que representan la mayor parte del tráfico; el origen conserva las transacciones, los informes y todo lo que exige el modelo relacional completo. El resultado suele mejorar la latencia percibida más que cualquier optimización interna del origen, y lo hace sin tocar el sistema que nadie quiere tocar.

Puestas juntas las ganancias y las pérdidas, el balance de elegir Cloudflare se puede escribir sin adornos por ninguno de los dos lados.

Lo que se gana Lo que se pierde
Cero cold start y presencia global sin regiones Un entorno de ejecución restringido
Almacenamiento y cómputo del mismo modelo, unidos por bindings Ecosistema con huecos y menos respuestas escritas
Sin infraestructura que aprovisionar ni escalar Menos control fino cuando lo necesitas de verdad
Facturación por CPU y salida sin coste en R2 Dependencia de APIs sin equivalente fuera
Un sistema que cabe en la cabeza de una persona Menos gente contratable con experiencia previa

Queda una frontera final que no es técnica sino normativa: la residencia de los datos. Cuando un contrato exige que ciertos datos no salgan de una jurisdicción, un modelo que ejecuta en todas partes obliga a razonar con cuidado sobre dónde se procesa cada cosa. La plataforma da herramientas para acotarlo —jurisdicciones para R2 y para la ubicación de los objetos durables, control explícito de dónde vive la primaria—, pero la carga de demostrarlo ante un auditor es tuya, y es un trabajo real que conviene presupuestar antes de firmar nada.

⚖️

Cuatro apuestas, no cuatro calidades

Generalidad en AWS, experiencia de despliegue en Vercel, portabilidad en Fly y radicalidad del isolate en Cloudflare. Cada una gana en su terreno.

💸

Las unidades no se convierten

Pagar CPU frente a pagar reloj, salida gratis frente a salida cara y cero en reposo frente a capacidad reservada cambian la factura por factores, no por porcentajes.

🔱

El lock-in útil existe

Atarse a una capacidad que no se puede replicar es una decisión legítima. Atarse sin saberlo, y con la lógica de negocio dentro de los handlers, no lo es.

Elegir plataforma es elegir qué restricción prefieres, porque ninguna te libera de todas

La forma más honesta de leer este panorama es dejar de preguntar cuál es mejor y empezar a preguntar qué restricción estás dispuesto a aceptar, porque las cuatro imponen una y ninguna las evita todas. AWS te da libertad de ejecución absoluta y te cobra en complejidad operativa permanente: puedes hacer cualquier cosa, siempre que dediques una fracción estable de tu equipo a mantener la máquina que lo permite. Vercel te libera del despliegue y te cobra en profundidad: todo lo que no sea render acaba siendo integración de terceros que tú operas. Fly te libera del modelo de programación y te cobra en operación de máquinas y regiones, que es un problema más pequeño que el de AWS pero sigue siendo tuyo. Cloudflare te libera de la infraestructura entera —no hay servidores, ni regiones, ni escalado, ni cold start, ni salida que pagar— y te cobra en un entorno de ejecución restringido y en un ecosistema que todavía tiene huecos. Esa es la transacción completa, y quien la presente como si solo tuviera una cara está vendiendo algo. Ahora bien, hay un argumento que sí distingue a Cloudflare del resto y que no es de marketing: es la única de las cuatro donde el cómputo, el almacenamiento, la coordinación, la cola, la caché y la inferencia fueron diseñados para el mismo modelo de ejecución y se conectan por bindings en lugar de por red autenticada. En las otras plataformas ensamblas piezas excelentes que no se conocen entre sí, y buena parte de tu trabajo consiste en escribir el pegamento, gestionar sus credenciales y depurar sus fronteras. Aquí ese pegamento no existe porque no hace falta, y esa coherencia es el verdadero producto: no la latencia, que es lo que se anuncia, sino el hecho de que un sistema entero quepa en la cabeza de una persona. Lo que hay que tener claro es que esa coherencia se compra con la restricción del isolate, y que si tu problema choca de frente con ella, ninguna elegancia arquitectónica te va a compensar.

⚔️ Defiende y ataca tu propia elección
  1. Escribe el argumento más fuerte a favor de no usar Cloudflare para un proyecto concreto que tengas en mente.
  2. Calcula qué fracción del tiempo de ejecución de tu ruta principal es espera de red y qué implicaría eso en un modelo que factura reloj.
  3. Estima cuántas semanas costaría llevar ese sistema a otra plataforma y qué parte de ese coste es lógica de negocio.
  4. Identifica una dependencia propietaria que uses sin ganar nada a cambio y otra que compre una capacidad irreemplazable.
  5. Diseña la variante híbrida: qué se queda donde está y qué se pone delante en el edge, con la razón de cada decisión.