|

Costos ocultos AWS: lo que pagás sin darte cuenta

En pocas palabras: Un NAT Gateway inactivo en AWS factura por hora igual que uno en uso, más ~USD 3,65 mensuales si su Elastic IP queda sin liberar. Load balancers con RequestCount en cero 7 días e instancias EC2 bajo 5% de CPU siguen su misma lógica de cobro por asignación, no por consumo, según guía técnica del 30 de septiembre de 2026.

Un NAT Gateway inactivo en AWS cuesta lo mismo que uno activo, porque el medidor arranca al crearlo y no cuando alguien lo usa. Detectarlo requiere revisar la métrica BytesOutToDestination durante 14 días consecutivos en cero, según una guía técnica publicada el 30 de septiembre de 2026 que documenta el método completo de detección y limpieza.

Los costos ocultos AWS son los cargos que se acumulan por recursos de infraestructura que quedan asignados pero sin tráfico real: NAT Gateways sin conexiones, load balancers con cero requests, instancias EC2 con CPU por debajo del 5% e instancias RDS dormidas. AWS factura por asignación, no por consumo, así que el medidor corre desde el aprovisionamiento, sin importar si alguien usa el recurso.

En 30 segundos

  • Un NAT Gateway huérfano sigue facturando aunque no reenvíe bytes, y su Elastic IP asociada suma unos USD 3,65 extra por mes si no se libera.
  • Un load balancer con RequestCount en cero durante 7 días consecutivos es candidato a borrado, según el método documentado el 30/09/2026.
  • CPU por debajo del 5% sostenido es el umbral de referencia para marcar una instancia EC2 como subutilizada, sin necesidad de machine learning.
  • Los log groups de CloudWatch con retentionInDays en null guardan datos para siempre y siguen sumando a la factura sin que ninguna alarma avise.

¿Por qué AWS cobra por recursos que nadie está usando?

AWS cobra por la asignación del recurso, no por su consumo real. El medidor de un NAT Gateway o de un Application Load Balancer empieza a correr en el momento en que termina el aprovisionamiento, y sigue corriendo aunque el target group nunca reciba un health check exitoso. La factura no distingue entre un recurso sirviendo tráfico de producción y otro olvidado en una cuenta de staging.

Hay tres causas estructurales detrás de esto. La primera es la falta de un camino de decomisión: alguien crea el recurso para cumplir un deadline y después sigue con otra cosa, sin que ningún ticket cierre el NAT Gateway ni ninguna alerta salte cuando el request count cae a cero y se queda ahí.

La segunda es la erosión del ownership. Pasados 30 días, el ingeniero que provisionó el recurso ya rotó de equipo, el tag de costos nunca existió o apunta a un centro de costos que ya no rastrea esa cuenta. Sin un dueño identificado, nadie recibe la línea de la factura y nadie actúa. Te puede servir nuestra cobertura de automatizar la detección de estos recursos con n8n.

¿Y la tercera? La ambigüedad del umbral. No hay una definición compartida de qué significa “inactivo” según el tipo de recurso: ¿qué piso de CPU marca una instancia como recuperable? ¿Qué cantidad de conexiones habilita apagar una RDS? Sin umbrales acordados, cada limpieza se vuelve una negociación en lugar de una ejecución directa.

¿Cómo detectar un NAT Gateway sin tráfico real?

Se detecta consultando la métrica BytesOutToDestination vía get-metric-statistics, con el campo Period en 86400 segundos, durante 14 días consecutivos en cero. Ese valor confirma que ningún cliente detrás del gateway está enviando tráfico hacia internet, según la documentación oficial de métricas de NAT Gateway de AWS.

Una ventana más corta arruina la detección: un batch job nocturno genera un pico diario válido que tapa siete días idle a cada lado. Por eso el mínimo recomendado son 14 días, no menos.

Ojo con esto: después de que la métrica marca un candidato, hay que llamar a describe-nat-gateways y leer el campo State. Un gateway en estado available con cero bytes forwarded está confirmado como idle. Uno en deleting o failed factura igual pero necesita otro tratamiento, y borrarlo solo por la señal de la métrica arriesga actuar sobre un recurso a mitad de transición.

La trampa que la mayoría de las guías omite: cada NAT Gateway tiene una Elastic IP asociada. Borrar el gateway sin liberar esa IP la deja asignada a tu cuenta indefinidamente, a razón de aproximadamente USD 3,65 por mes por dirección. El paso de liberación (release-address) es una acción separada, y conviene ejecutarla justo después de cada borrado, no al final de un lote. Batchear esa liberación deja una ventana donde la IP sigue asignada y facturando.

¿Cómo confirmar que un load balancer está realmente inactivo?

Se confirma con la métrica RequestCount en cero durante 7 días consecutivos, usando Period de 86400 segundos y estadístico Sum. Después hay que verificar con describe-load-balancers que el campo State.Code esté en active: un balanceador activo con cero requests está confirmado como idle. Sobre eso hablamos en otros costos ocultos que inflan tu factura serverless.

El punto es que borrar solo el balanceador no alcanza. Cada target group queda huérfano, y aunque no acumula cargo horario directo por sí solo, el problema aparece después: el próximo ingeniero crea un load balancer nuevo, le adjunta ese grupo viejo y reanuda la facturación sin darse cuenta de que nunca llegó tráfico real al backend.

El orden importa. Primero deregister-targets, después delete-target-group, y al final se borra el balanceador. Invertir esa secuencia produce un error de dependencia y una limpieza incompleta que hay que rehacer.

¿Qué umbral de CPU marca una instancia EC2 como ociosa?

El umbral de referencia es CPU por debajo del 5% sostenido, medido sin necesidad de machine learning: alcanza con una detección basada en reglas fijas contra métricas de CloudWatch. Ese piso funciona como señal de subutilización, no de inactividad total, porque una instancia puede estar corriendo un proceso liviano y seguir facturando por hora.

Acá está el detalle que suele pasar desapercibido: AWS cobra exactamente lo mismo por una instancia al 3% de CPU que por una al 80%. El medidor no distingue consumo real, solo asignación. Una instancia t3.large ociosa y una t3.large a plena carga generan la misma línea en la factura.

¿Los CloudWatch Logs también generan costos ocultos?

Sí, y es el caso que la detección de facturación suele pasar por alto, porque el costo se acumula en la capa de logging en lugar de en el cómputo o la red que los equipos ya monitorean. La detección arranca con describe-log-groups, que devuelve cada log group junto a su campo retentionInDays. Si ese campo es null, no hay política de retención y AWS guarda los datos para siempre a la tarifa estándar. Ya lo cubrimos antes en configurar bien la trust policy en tus pipelines.

El control es uno solo: el campo retentionInDays. Null significa retención permanente. Fijarlo en 30 o 90 días detiene la acumulación futura de inmediato con put-retention-policy.

El tema es que esto se rompe cuando las funciones Lambda o las tareas de ECS que generaban esos logs ya se decomisionaron. El log group se queda en la cuenta, sin ingesta nueva pero facturando por los bytes almacenados de corridas pasadas. Detectar esto exige un paso extra: describe-log-streams y revisar lastEventTimestamp en cada stream. Un grupo sin streams, o con el último evento más viejo que tu ventana de decomisión, es candidato a borrado directo, no a una simple política de retención (poner 30 días de retención en un grupo que nunca va a recibir otro evento no ahorra nada frente a borrarlo).

Comparativa de recursos inactivos en AWS

RecursoMétrica de detecciónUmbralTrampa oculta
NAT GatewayBytesOutToDestination0 bytes durante 14 díasElastic IP huérfana, ~USD 3,65/mes
Load BalancerRequestCount0 requests durante 7 díasTarget group huérfano
Instancia EC2CPU UtilizationMenos del 5% sostenidoFactura igual con 3% o 80% de uso
CloudWatch LogsretentionInDaysNull (retención indefinida)Log groups de recursos ya borrados

¿Cómo evitar que los recursos inactivos vuelvan a acumularse?

Se evita con tagging obligatorio en el momento de creación: cada recurso necesita etiquetas owner, env y ttl, y el pipeline de infraestructura como código rechaza lo que no las tenga. Esto funciona bien cuando IaC es el único camino de aprovisionamiento. Se rompe cuando alguien crea un recurso desde la consola durante una respuesta a incidente, porque ese chequeo del pipeline nunca corre y el recurso entra a la cuenta sin tag y sin rastreo.

Lo interesante es que la detección programada le gana a la auditoría reactiva. Correr las consultas de idle cada 14 días, en lugar de esperar a que alguien note un pico en la factura, cambia el costo total: un recurso ocioso detectado el día 1 del ciclo de facturación sale más barato que el mismo recurso detectado el día 28.

Los checklists de decomisión ayudan si se aplican al cierre del ticket, no después. Cuando se borra un recurso de cómputo o de red, el ticket tiene que incluir subtareas explícitas para log groups asociados, Elastic IPs y reglas de security groups. Sin eso, esos tres elementos quedan huérfanos en la cuenta 60 días después, sin que nadie los note. Más contexto en diseñar una arquitectura AWS de producción sólida.

Si tu problema de fondo es que preferís no lidiar con esta complejidad de facturación por asignación, en Latinoamérica hay alternativas de infraestructura con costos más predecibles: proveedores como donweb.com ofrecen hosting y VPS donde la factura no depende de que te olvides de apagar algo en una cuenta de staging.

Qué está confirmado y qué no

  • Confirmado: AWS factura por asignación de recursos, no por consumo, y las métricas BytesOutToDestination y RequestCount son los mecanismos documentados por AWS para detectar inactividad.
  • No confirmado: no hay cifra oficial de AWS sobre qué porcentaje del gasto global en la nube corresponde a recursos inactivos.
  • No confirmado: no queda claro si Compute Optimizer ya cubre target groups huérfanos o log groups sin política de retención, o si eso sigue siendo terreno de scripts manuales.

Errores comunes al limpiar recursos inactivos en AWS

  • Borrar el NAT Gateway sin liberar la Elastic IP: la dirección queda asignada a la cuenta y sigue facturando indefinidamente, aunque el gateway ya no exista.
  • Borrar el load balancer antes de desregistrar los targets: produce un error de dependencia y deja el target group huérfano, listo para que alguien lo reactive sin querer.
  • Correr la detección con menos de 14-15 días de historial en CloudWatch: get-metric-statistics devuelve cero puntos de datos y cada recurso aparece como idle por defecto, generando falsos positivos.
  • Poner retención de 30 o 90 días a un log group que ya no recibe eventos: si el grupo viene de un Lambda decomisionado, la retención no ahorra nada frente a borrarlo directamente.

Preguntas Frecuentes

¿Cuánto cuesta un NAT Gateway sin usar por mes?

Cuesta lo mismo que uno con tráfico activo, porque AWS factura por hora desde el aprovisionamiento. Además, si no liberás la Elastic IP asociada después de borrarlo, sumás cerca de USD 3,65 mensuales extra por esa dirección.

¿Cómo saber si un load balancer está inactivo en AWS?

Se confirma revisando la métrica RequestCount con estadístico Sum: si el valor es cero durante 7 días consecutivos, y describe-load-balancers muestra el balanceador en estado active, está confirmado como inactivo.

¿Qué porcentaje de CPU indica que una instancia EC2 está subutilizada?

Una CPU sostenida por debajo del 5% es el umbral de referencia para marcar una instancia como subutilizada. Este criterio se aplica con reglas fijas contra métricas de CloudWatch, sin necesidad de modelos de machine learning.

¿Cómo reducir la factura de AWS eliminando recursos inactivos?

Se reduce corriendo detección con las métricas correctas por tipo de recurso, verificando el estado antes de borrar, y limpiando dependencias como target groups y Elastic IPs en el orden correcto. Hacerlo cada 14 días, en lugar de después de un pico de gasto, evita que el costo se acumule.

¿Por qué AWS sigue cobrando por un recurso que nadie usa?

Porque el modelo de facturación de AWS es allocation-based: el medidor arranca en el momento en que termina el provisioning, no cuando llega tráfico real. La plataforma no distingue entre un recurso sirviendo producción y uno olvidado en una cuenta de staging.

Conclusión

Los costos ocultos AWS no son un problema de detección, son un problema de proceso. Las métricas para encontrar NAT Gateways, load balancers y log groups ociosos están documentadas y son simples de correr. Lo que falta en la mayoría de las cuentas es un gate automático que impida que el próximo ciclo de aprovisionamiento genere el mismo desperdicio.

Si tu equipo maneja varias cuentas de AWS, el paso concreto es correr esta detección con una cadencia fija (cada 14 días, no después de que alguien note la factura) y cerrar cada ticket de decomisión con las tres subtareas que casi siempre se saltean: log groups, Elastic IPs y target groups. Eso, sumado a tags obligatorios de owner, env y ttl en el pipeline de IaC, es lo que separa una limpieza puntual de un proceso que realmente sostiene el ahorro en el tiempo.

Fuentes

Te puede interesar...