El precio que nadie te dice de seguir las buenas prácticas de AWS al pie de la letra
ArquitecturaInfraestructura

El precio que nadie te dice de seguir las buenas prácticas de AWS al pie de la letra

Repartir tu app y tu base de datos entre zonas de disponibilidad es el consejo estándar de alta disponibilidad. Nadie menciona que cada consulta que cruza esa frontera paga latencia y factura real.

Daniel Jordan
8 min read
Compartir:

El síntoma: la arquitectura "correcta" que sale cara

Una aplicación desplegada en 3 AZs por alta disponibilidad — tal como recomienda cualquier guía de arquitectura — acumula una línea de factura que nadie sabe explicar del todo: "transferencia de datos entre zonas". No es un error de configuración. Es el coste normal de que la aplicación en la AZ-a hable constantemente con la base de datos en la AZ-b.

Qué pasa realmente al cruzar una AZ

Dentro de la misma región de AWS, el tráfico entre Availability Zones distintas se factura aunque vaya por IP privada, dentro de la misma VPC: $0.01 por GB en cada dirección — $0.02/GB contando ida y vuelta.

A eso se suma la latencia. El propio blog de arquitectura de AWS documenta el patrón AZ Affinity y da una cifra concreta: cada cruce de AZ añade entre 1 y 1.5ms de latencia. En el peor caso descrito por AWS, con 8 cruces de AZ en una cadena de llamadas, el procesamiento no puede bajar de 12ms solo en esa latencia — antes de que la base de datos haga nada. En un escenario típico (p50), 1.5ms de latencia cruzada más 8ms de procesamiento real dan 20ms totales, la mitad de los cuales no aportan nada de trabajo útil.

Por qué existe ese peaje: la física detrás de la frontera

Esto no es una decisión arbitraria de precios. Cada AZ es uno o más centros de datos con alimentación, refrigeración y conectividad propias, y AWS las separa deliberadamente hasta 60 millas (~100 km) entre sí para que un fallo local (inundación, incendio, corte eléctrico) no afecte a más de una zona a la vez — lo suficientemente cerca, eso sí, para sostener replicación síncrona con latencia de un solo dígito de milisegundo (AWS Fault Isolation Boundaries whitepaper).

Esa distancia se cubre con fibra metropolitana dedicada, propiedad de AWS, no con tránsito público. En noviembre de 2025 AWS anunció el despliegue de su propio transpondedor DWDM de nueva generación (primero en rutas metro, después en long-haul), con una mejora medida de 73% más ancho de banda y ~35% menos consumo eléctrico frente al hardware de terceros que usaban antes — cifra de AWS, no una propiedad genérica de la tecnología DWDM.

Todo el tráfico entre AZs se cifra automáticamente en la capa física antes de salir de las instalaciones de AWS, con independencia del tipo de instancia. Si además usas tipos de instancia compatibles con Nitro dentro de la misma VPC (o VPCs peereadas, sin balanceador ni Transit Gateway de por medio), se añade una segunda capa de cifrado AES-256-GCM por hardware a velocidad de línea, sin coste de rendimiento (AWS EC2 Data Protection docs; AWS Nitro System Security whitepaper).

La cifra de AWS de 1–1.5ms por cruce (citada arriba, del propio blog de AZ Affinity) es coherente con la física: la luz viaja por fibra a ~2/3 de c (~200.000 km/s), así que un salto metropolitano de 50–80 km de ida y vuelta cuesta solo entre 0.5 y 0.8ms de propagación — el resto es conmutación, encapsulado y cifrado. Es una estimación razonada a partir de la física, no una cifra publicada por AWS con ese desglose exacto.

Un efecto colateral menos conocido: el MTU no es uniforme en toda la red de AWS. Dentro de una VPC (misma o distinta AZ) y en VPC Peering dentro de la misma región se soportan jumbo frames de 9001 bytes; en cuanto el tráfico pasa por un Transit Gateway, el límite baja a 8500 bytes; y en VPC Peering entre regiones distintas cae a los 1500 bytes estándar de Ethernet (AWS Transit Gateway docs). Mezclar TGW con instancias configuradas a 9001 sin Path MTU Discovery habilitado provoca caídas silenciosas de paquetes — un problema real y documentado, no teórico.

El coste, con números reales

Un caso documentado por un ingeniero auditando su propia infraestructura: una organización con 80 servicios internos, replicados en 4 entornos (prod/staging/QA/dev), acumulaba más de 62.000€ al año solo en costes fijos de los balanceadores necesarios para gestionar el tráfico entre zonas — sin contar el tráfico cruzado en sí, que se factura aparte, dos veces por petición (app→balanceador y balanceador→servicio).

El patrón de solución: AZ Affinity

AWS documenta dos cambios concretos para reducir esto sin renunciar a la alta disponibilidad:

  1. Desactivar el balanceo cruzado de zona en el grupo de destino del load balancer (cross-zone load balancing), para que el tráfico se quede dentro de la misma AZ salvo cuando haga falta.
  2. Mantener los servicios fuertemente acoplados (que se llaman constantemente entre sí) en la misma AZ, reservando el cruce entre zonas para el failover ante caída — no para el tráfico habitual.

La disponibilidad no se pierde: sigues teniendo réplicas en varias AZs. Lo que cambia es que el tráfico normal ya no cruza la frontera en cada petición, solo cuando una AZ completa falla.

El mismo patrón en Kubernetes y EKS

Si tu plataforma corre sobre Kubernetes, este problema tiene nombre propio y solución nativa. El comportamiento por defecto de kube-proxy reparte las peticiones entre pods de forma pseudoaleatoria, sin tener en cuenta la zona — en un clúster repartido uniformemente entre 3 AZs, eso significa que aproximadamente dos tercios de las llamadas entre servicios cruzan una frontera de AZ sin necesidad.

Kubernetes lo corrige con Topology Aware Routing (llamado Topology Aware Hints antes de la versión 1.27 — activable con la anotación service.kubernetes.io/topology-mode: Auto), que hace que el proxy de cada nodo priorice endpoints en su misma zona. Tiene una salvaguarda importante: si la distribución de capacidad entre zonas se desequilibra por encima de un 20% (Overload Threshold), el controlador desactiva automáticamente las rutas preferentes por zona para no sobrecargar los pods de la zona más pequeña, y vuelve al balanceo global aleatorio — lo cual reactiva en silencio la factura de tráfico cruzado (documentación oficial de Kubernetes; blog de contenedores de AWS con el análisis del algoritmo). Esto es exactamente lo que puede pasar si Karpenter concentra nodos en unas pocas AZs por agotamiento de capacidad Spot.

Desde Kubernetes 1.30 existe además el campo nativo trafficDistribution: PreferClose, una alternativa más determinista y menos heurística que las hints, que ha ido madurando en las versiones siguientes (KEP-4444). Para que cualquiera de los dos mecanismos funcione de forma sostenida, hace falta combinarlo con Topology Spread Constraints (maxSkew) que mantengan las réplicas repartidas de forma simétrica entre zonas — sin eso, la propia irregularidad del clúster acaba desactivando la optimización.

Una advertencia importante: esto no es universal en todas las nubes

Azure eliminó este cargo por completo. Google Cloud sí factura tráfico entre zonas de forma similar a AWS. Si tu infraestructura vive en Azure, este problema específico de coste no aplica igual — pero la latencia por cruzar zonas sí sigue existiendo, sea cual sea el proveedor.

Criterio de decisión

¿Tus servicios más "conversadores" entre sí (los que se llaman en cada petición, no ocasionalmente) están desplegados deliberadamente juntos en la misma AZ, o simplemente donde el orquestador decidió colocarlos? Si es lo segundo, hay margen de mejora sin tocar una sola línea de código — es una decisión de despliegue, no de arquitectura de aplicación.

Referencias

Lecturas relacionadas

Tags:#aws#disponibilidad#costes-cloud#latencia#infraestructura