☁️ Cloud, DevOps & Infraestructura

FinOps para developers: cómo no reventar la factura cloud

La factura cloud no la decide solo quien negocia el contrato con el proveedor. La decide, línea a línea, quien escribe el código: qué región elige, cuánto sobreaprovisiona, cuántos datos mueve de más.

📅 21 de julio de 2026 ⏱️ 10 min de lectura ✍️ Equipo ProgramacionWebs

Durante años, el coste cloud fue un problema de otro departamento: finanzas veía la factura a fin de mes, alguien se sorprendía, y la conversación terminaba en “hay que revisar esto” sin que cambiara nada en el código que lo estaba generando. FinOps —la disciplina que junta ingeniería, finanzas y producto alrededor de decisiones de coste— ha dejado claro algo que debería haber sido obvio desde el principio: la factura no la decide el contrato con el proveedor, la decide, línea a línea, quien escribe el código y diseña la arquitectura. Una elección de región, un timeout mal puesto, un log que nadie borra, todo eso se traduce en dinero real con un desfase de semanas entre la decisión y la línea de la factura.

Este artículo no es sobre cómo negociar descuentos por volumen con tu proveedor cloud. Es sobre las decisiones técnicas —las que toma un developer, no un procurement— que más impactan en el coste, y sobre cómo conseguir visibilidad de ese coste antes de que aparezca como sorpresa.

Egress: el coste que nadie estima antes de lanzar

Los principales proveedores cloud regalan (o casi) que entren datos a su red. Sacarlos, no. El tráfico de salida hacia internet, y en muchos casos incluso el tráfico entre regiones o zonas de disponibilidad del mismo proveedor, se factura por gigabyte movido, y esa partida puede representar una fracción significativa de la factura total en servicios que mueven volúmenes grandes de datos hacia el usuario final o hacia otro proveedor.

Las decisiones de arquitectura que más influyen en esta partida:

  • Servir contenido estático directamente desde tu backend en vez de desde un CDN. Cada imagen, cada bundle de JavaScript servido desde tu propio compute paga tarifa de egress completa; servido desde una CDN (Cloudflare, CloudFront, Fastly) suele salir sensiblemente más barato, y en el caso de Cloudflare el egress hacia internet desde su red está incluido sin coste adicional en la mayoría de sus productos.
  • Comunicación entre servicios en regiones o zonas distintas por defecto, sin necesidad real. Un microservicio en eu-west-1 llamando constantemente a una base de datos en us-east-1 paga tráfico entre regiones en cada petición, además de la latencia. Colocar servicios que se hablan mucho entre sí en la misma región —o al menos en la misma zona de disponibilidad cuando el volumen es alto— es una decisión de arquitectura con impacto de coste directo, no solo de latencia.
  • Devolver payloads más grandes de lo necesario. Una API que devuelve el objeto completo cuando el cliente solo necesita tres campos multiplica el egress por cada llamada. Paginación real, proyección de campos y compresión (gzip/br en las respuestas HTTP) no son solo buenas prácticas de rendimiento: son ahorro de coste medible a escala.
  • Replicar datos entre nubes o entre proveedores sin necesidad. La factura de “salir” de un proveedor hacia otro es, en muchos casos, más alta que moverse dentro del mismo ecosistema — un argumento de peso, entre varios, para pensar dos veces una estrategia multi-cloud que no resuelve un problema real de disponibilidad.

Cold starts: rendimiento y coste son la misma decisión

En arquitecturas serverless (funciones AWS Lambda, Cloudflare Workers, Vercel Functions) el modelo de facturación premia mantener las funciones pequeñas, rápidas de inicializar y ejecutándose solo el tiempo estrictamente necesario. Un cold start —el tiempo que tarda la plataforma en inicializar una instancia nueva de tu función cuando no había ninguna caliente— no es solo un problema de latencia percibida por el usuario: cada inicialización adicional que tu diseño provoca es tiempo de cómputo que se factura, y en escenarios de alta concurrencia con muchas instancias frías simultáneas, ese coste de arranque se multiplica.

Decisiones de código con impacto directo:

  • Dependencias pesadas cargadas en el arranque de la función. Un SDK completo importado cuando solo necesitas un cliente HTTP ligero incrementa el tiempo de cold start en cada instancia nueva. El tree-shaking y evitar imports innecesarios en el punto de entrada de una función serverless no es solo higiene de bundle, es coste de arranque repetido miles de veces al día.
  • Conexiones a base de datos abiertas de forma ineficiente. Abrir una conexión nueva a la base de datos en cada invocación fría, sin connection pooling diseñado para el modelo serverless (proxies como RDS Proxy o soluciones de pooling a nivel de edge), añade latencia y, en bases de datos facturadas por tiempo de conexión activa, coste directo.
  • Funciones “todo en uno” en vez de funciones específicas por ruta. Una única función Lambda gigante que gestiona todas las rutas de una API arranca más lenta (más código que inicializar) que varias funciones pequeñas y específicas, cada una con solo las dependencias que necesita su ruta concreta.
  • Elegir el runtime y la memoria asignada sin medir. En AWS Lambda, la CPU disponible escala junto con la memoria asignada; asignar de más “por si acaso” no solo cuesta más por invocación, a veces ni siquiera mejora la latencia si el cuello de botella real es de I/O, no de cómputo. Medir con la propia herramienta de power tuning del proveedor antes de fijar ese valor a ojo evita las dos formas de error — pagar de más y tener rendimiento pobre a la vez.

Sobreaprovisionamiento: el gasto invisible más grande

De todas las fuentes de gasto cloud desperdiciado, el sobreaprovisionamiento de recursos reservados —instancias, bases de datos, clústeres de Kubernetes— dimensionados muy por encima de lo que realmente consumen es sistemáticamente la partida más grande, y también la más invisible: nadie recibe una alerta cuando una instancia lleva meses funcionando al 8% de su capacidad reservada, porque técnicamente no está fallando.

En Kubernetes en concreto, esto se ve con mucha frecuencia en los resources.requests que mencionamos al hablar de Kubernetes para developers: un equipo que copia y pega valores de cpu/memory de otro servicio sin medir el consumo real de su propia aplicación termina reservando capacidad que nunca se usa, y esa capacidad reservada —aunque no se consuma— es la que determina cuántos nodos necesita el clúster, y por tanto la factura.

# Antes de fijar esto a ojo, mide el consumo real con
# kubectl top pod o con las métricas de tu stack de observabilidad
resources:
  requests:
    cpu: "100m"      # no "500m" copiado de otro servicio
    memory: "128Mi"
  limits:
    cpu: "300m"
    memory: "256Mi"
graph TD
Codigo["Decisión en código / arquitectura"] --> Egress["Egress: CDN, colocación, payloads"]
Codigo --> Cold["Cold starts: dependencias, pooling, tamaño de función"]
Codigo --> Sobre["Sobreaprovisionamiento: requests/limits, instancias reservadas"]
Codigo --> Storage["Almacenamiento: retención de logs, snapshots, tiers"]
Egress --> Factura["Factura cloud"]
Cold --> Factura
Sobre --> Factura
Storage --> Factura

Fuera de Kubernetes, el mismo patrón se repite con instancias reservadas o comprometidas a largo plazo dimensionadas para un pico de tráfico que ocurre dos días al año, en vez de usar autoscaling real que ajuste la capacidad a la demanda del momento. El rightsizing —ajustar el tamaño de un recurso a su consumo real, medido, no estimado— es la palanca de ahorro con mejor relación esfuerzo/impacto de todo FinOps, precisamente porque no requiere cambiar arquitectura, solo dejar de adivinar.

Almacenamiento que nadie borra

Menos comentado que egress o cómputo, pero acumulativo: logs con retención indefinida, snapshots de bases de datos que nadie limpia, buckets con versionado activado que guardan cada versión histórica de cada archivo para siempre, entornos de staging con volúmenes del tamaño de producción. Ninguna de estas partidas es dramática por sí sola en un mes concreto; todas crecen mes a mes sin que nada las frene, porque borrar datos da más miedo (por si acaso hacen falta) que dejarlos acumularse.

Prácticas concretas con impacto medible:

  • Políticas de ciclo de vida (lifecycle policies) en almacenamiento de objetos: mover automáticamente a un tier más barato, o borrar directamente, datos que superan una antigüedad definida.
  • Retención de logs con un límite explícito en vez de “para siempre por defecto”, diferenciando qué logs necesitan conservarse por auditoría o compliance de los que son solo ruido operativo de corta vida útil.
  • Revisar snapshots y backups huérfanos de recursos que ya no existen — es sorprendentemente común pagar por el respaldo de algo que se dio de baja hace meses.

Dar visibilidad de coste sin frenar a nadie

La respuesta organizativa a todo esto, cuando se hace bien, no es un proceso de aprobación manual para cada despliegue —eso solo añade fricción sin cambiar el comportamiento de fondo—. Es hacer visible el coste en el mismo lugar donde ya se toman las decisiones técnicas, para que el criterio de coste entre en la cabeza de quien escribe el código en el momento en que lo escribe, no un mes después en una reunión.

La FinOps Foundation formalizó esto con FOCUS (FinOps Open Cost and Usage Specification), un estándar abierto que normaliza el formato de los datos de facturación entre proveedores distintos —AWS, Azure, Google Cloud y otros ya exportan datos en este formato—, de forma que un equipo de plataforma pueda construir un único panel de coste sin tener que traducir manualmente entre el formato propietario de cada proveedor.

Algunas prácticas concretas que trasladan esto al día a día de un equipo de desarrollo:

  • Etiquetado (tagging) obligatorio y consistente de todo recurso cloud por equipo, servicio y entorno, validado en el propio pipeline de infraestructura como código — sin etiquetas correctas, ningún panel de coste puede atribuir el gasto a quien lo generó.
  • Alertas de presupuesto por servicio, no solo una alerta global de la cuenta completa, para que la desviación se detecte cerca de quien puede actuar sobre ella.
  • Coste como criterio explícito en revisiones de arquitectura, junto a rendimiento y seguridad, especialmente antes de adoptar un servicio gestionado nuevo cuyo modelo de precios no se entiende del todo todavía.
  • Revisar el coste de un cambio de infraestructura en el mismo pull request que lo introduce, cuando la herramienta de infraestructura como código lo permite (algunos proveedores y herramientas de terceros estiman el delta de coste de un plan de Terraform antes de aplicarlo).

Ninguna de estas prácticas requiere que un developer se convierta en especialista en pricing de la nube. Requiere que el coste deje de ser un dato que solo existe en un informe ajeno, y pase a ser una señal más —como la latencia o la tasa de errores— visible en el propio flujo de trabajo de quien construye el sistema. La plataforma que ya centraliza CI/CD y despliegue, si además expone esa visibilidad de coste desde el primer día, evita que sobreaprovisionar se convierta en el camino de menor resistencia — algo que conecta directamente con el diseño de una buena plataforma interna, como vimos en Platform Engineering.

Compartir