Optimización de costos en la nube: deja de pagar de más por tu MVP
La mayoría de las startups desperdician el 40-60% de su presupuesto en la nube. Aquí tienes una guía práctica para dimensionar correctamente tu infraestructura sin sacrificar fiabilidad.

El último trimestre audité la factura de AWS de una startup y descubrí que estaban gastando $2,800/mes en infraestructura que podría funcionar cómodamente por $900. Tenían una t3.2xlarge ejecutando una API Node.js que alcanzaba un pico de 12% de utilización de CPU. Tres Elastic IPs sin usar inactivas a $3.65/mes cada una. Un despliegue RDS Multi-AZ para una base de datos con 200 filas. Un NAT gateway enrutando tráfico que podría haber ido a través de un VPC endpoint gratis. Nada de esto era malicioso ni particularmente descuidado — era la acumulación de decisiones de "simplemente provisiona algo que funcione" tomadas durante un sprint para lanzar.
Esto es la norma, no la excepción. La mayoría de las startups en etapa temprana desperdician el 40-60% de su gasto en la nube porque nadie en el equipo tiene el tiempo o el incentivo para optimizar costos cuando hay funcionalidades que lanzar. El problema se multiplica: una vez que la infraestructura está provisionada y funcionando, nadie la toca.
Las mayores trampas de costos que sigo viendo
Antes de profundizar en las soluciones, ayuda entender a dónde realmente va el dinero. Estas son las trampas que encuentro con más frecuencia al revisar la infraestructura de startups.
Instancias de cómputo sobredimensionadas
Esta es la mayor fuente de desperdicio. Los equipos eligen un tamaño de instancia durante la configuración inicial — usualmente basándose en un artículo de blog o una mentalidad de "por si acaso" — y nunca lo revisan. He visto instancias m5.xlarge ejecutando cron jobs que se ejecutan por 30 segundos cada hora. La instancia permanece inactiva 59.5 minutos, quemando $0.192/hora ($140/mes) para hacer esencialmente nada.
La causa raíz es psicológica: nadie quiere ser la persona que subdimensionó el servidor y causó una caída. Así que todos redondean hacia arriba. Dos veces.
# Check your EC2 instance CPU utilization over the past 2 weeks
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-0abcdef1234567890 \
--start-time $(date -u -d '14 days ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
--period 3600 \
--statistics Average Maximum
Si tu CPU promedio está por debajo del 20% y tu pico por debajo del 50%, casi con certeza estás sobredimensionado. Baja uno o dos tamaños de instancia, monitorea durante una semana y ajusta.
Volúmenes EBS y snapshots olvidados
Cuando terminas una instancia EC2, los volúmenes EBS adjuntos no se eliminan automáticamente a menos que lo hayas configurado al lanzar. Esto significa que las instancias terminadas dejan volúmenes huérfanos que siguen facturando. He visto cuentas con docenas de volúmenes gp3 sin adjuntar, cada uno costando $0.08/GB/mes, totalizando cientos de dólares por almacenamiento que nadie usa.
Los snapshots son aún más sigilosos. Los scripts de backup automatizados crean snapshots diarios sin política de ciclo de vida, así que se acumulan indefinidamente. Un volumen de 500GB con snapshots diarios durante un año genera 365 snapshots, y aunque los snapshots de EBS son incrementales, los costos suman dinero real.
# Find all unattached EBS volumes
aws ec2 describe-volumes \
--filters Name=status,Values=available \
--query 'Volumes[*].{ID:VolumeId,Size:Size,Created:CreateTime}' \
--output table
# Find snapshots older than 90 days
aws ec2 describe-snapshots \
--owner-ids self \
--query 'Snapshots[?StartTime<=`2025-12-01`].{ID:SnapshotId,Size:VolumeSize,Date:StartTime}' \
--output table
NAT Gateway: el asesino silencioso del presupuesto
Los NAT gateways cuestan $0.045/hora ($32.40/mes) solo por existir, más $0.045 por GB de datos procesados. Para una startup que hace llamadas frecuentes a APIs externas desde subnets privadas, solo los cargos por procesamiento de datos pueden exceder $100/mes. He visto cargos de NAT gateway representar el 15-20% de la factura total de AWS de una startup pequeña.
La solución depende de qué tráfico fluye a través del NAT:
- Tráfico hacia servicios de AWS (S3, DynamoDB, SQS): Usa VPC Gateway Endpoints (gratis para S3 y DynamoDB) o Interface Endpoints ($7.20/mes cada uno, pero aún más baratos que NAT para tráfico de alto volumen).
- Tráfico a internet desde funciones Lambda: Considera si esas funciones realmente necesitan estar en un VPC. Muchas funciones Lambda se colocan en un VPC "por seguridad" cuando no acceden a ningún recurso del VPC.
- Tráfico saliente de bajo volumen: Una instancia NAT en una t4g.nano ($3.02/mes) maneja tráfico modesto a una fracción del costo del NAT gateway.
Cargos por transferencia de datos
AWS cobra $0.09/GB por datos que salen de una región, y el tráfico entre zonas de disponibilidad cuesta $0.01/GB en cada dirección. Estos cargos son invisibles hasta que dejan de serlo. Una arquitectura de microservicios con mucha comunicación distribuida en tres zonas de disponibilidad, con servicios llamándose cientos de veces por segundo, puede generar facturas sorprendentes por transferencia de datos.
La solución arquitectónica: co-localiza servicios que se comunican frecuentemente en la misma zona de disponibilidad para cargas de trabajo no críticas, o usa balanceadores de carga internos con afinidad de zona.
Dimensionamiento correcto: un enfoque sistemático
El dimensionamiento correcto no es un ejercicio de una sola vez. Es algo que deberías revisar trimestralmente. Aquí está el proceso que sigo.
Paso 1: Recopilar datos de utilización
AWS Compute Optimizer es gratuito y proporciona recomendaciones de dimensionamiento para EC2, EBS, Lambda y ECS. Actívalo y déjalo recopilar al menos 14 días de datos antes de actuar según sus recomendaciones.
Para análisis más granular, las métricas de CloudWatch son tu fuente principal de datos. Las métricas clave a vigilar:
- EC2: CPUUtilization, NetworkIn/Out, MemoryUtilization (requiere agente de CloudWatch)
- RDS: CPUUtilization, DatabaseConnections, FreeableMemory, ReadIOPS, WriteIOPS
- ElastiCache: CPUUtilization, CurrConnections, BytesUsedForCache
Paso 2: Categorizar cargas de trabajo
No toda carga de trabajo debería dimensionarse de la misma manera. Las categorizo en tres grupos:
Cargas de trabajo en estado estable (servidores API, bases de datos): Necesitan capacidad consistente. Dimensiona encontrando la instancia más pequeña que maneje la carga pico con un 30% de margen. Usa Reserved Instances o Savings Plans para la línea base.
Cargas de trabajo variables (procesamiento por lotes, servidores de build): Deberían usar Auto Scaling Groups con políticas de escalado apropiadas, o Spot Instances para trabajos por lotes tolerantes a fallos.
Cargas de trabajo periódicas (cron jobs, reportes programados): No deberían ejecutarse en instancias dedicadas en absoluto. Muévelas a Lambda, Fargate Spot o Step Functions.
Paso 3: Actuar incrementalmente
Nunca dimensiones todo a la vez. Baja un tamaño de instancia a la vez, monitorea durante una semana, luego decide si ir más lejos. El costo de un breve período de sobredimensionamiento es mucho menor que el costo de una caída en producción causada por un dimensionamiento agresivo.
Reserved Instances vs Savings Plans vs Spot
Aquí es donde ocurren los ahorros reales — 30-72% de descuento sobre precios bajo demanda — pero las mecánicas de compromiso son lo suficientemente confusas como para que muchas startups simplemente las eviten por completo.
Reserved Instances (RIs)
Te comprometes a un tipo de instancia específico en una región específica por 1 o 3 años. A cambio, obtienes un 30-40% de descuento (sin pago inicial, 1 año) hasta un 60% (todo por adelantado, 3 años). La trampa: si necesitas cambiar tipos de instancia, las RIs Standard no son flexibles. Las RIs Convertible ofrecen más flexibilidad con un descuento ligeramente menor (alrededor del 45% para 3 años todo por adelantado).
Cuándo usar RIs: Bases de datos y otras cargas de trabajo donde el tipo y tamaño de instancia son genuinamente estables. Las Reserved Instances de RDS casi siempre valen la pena — las bases de datos rara vez cambian de tamaño.
Savings Plans
Los Savings Plans son la alternativa moderna a las RIs para cómputo. Te comprometes a una cantidad en dólares de cómputo por hora (e.g., $0.10/hora) por 1 o 3 años. El compromiso se aplica automáticamente al uso de EC2, Fargate y Lambda, y es flexible entre familias de instancias, tamaños, sistema operativo y regiones.
Cuándo usar Savings Plans: Casi siempre preferibles a las RIs de EC2 para cargas de trabajo de cómputo. Los Compute Savings Plans ofrecen la mejor relación flexibilidad-descuento. Comienza con un compromiso que cubra tu gasto mínimo de línea base.
# Example: Calculating Savings Plan commitment
# Current on-demand spend: $500/month on EC2
# Minimum baseline (never drops below): $350/month
# Recommended Savings Plan commitment: $350/month = ~$0.48/hour
# Expected savings: ~30% on the committed amount = ~$105/month
# Remaining $150/month stays on-demand for flexibility
Spot Instances
Las Spot Instances ofrecen descuentos del 60-90% pero pueden ser interrumpidas con 2 minutos de aviso. Son ideales para:
- Agentes de build CI/CD (usa Spot Fleet con múltiples tipos de instancia)
- Trabajos de procesamiento por lotes que pueden hacer checkpoint y reanudar
- Entornos de desarrollo y staging
- Pruebas de carga
No son adecuadas para servidores API de producción, bases de datos o cualquier cosa que no pueda manejar una terminación repentina.
# Example: GitHub Actions self-hosted runner on Spot
# This saves roughly 70% compared to GitHub-hosted runners
# for compute-heavy builds
Resources:
SpotFleet:
Type: AWS::EC2::SpotFleet
Properties:
SpotFleetRequestConfigData:
IamFleetRole: !GetAtt SpotFleetRole.Arn
TargetCapacity: 2
AllocationStrategy: lowestPrice
LaunchSpecifications:
- InstanceType: c5.xlarge
SpotPrice: "0.06"
- InstanceType: c5a.xlarge
SpotPrice: "0.06"
- InstanceType: c6i.xlarge
SpotPrice: "0.06"
Modelos de costos serverless: no siempre más barato
Existe un mito persistente de que serverless es siempre más barato para startups. A menudo es más barato a baja escala, pero la economía se invierte conforme el tráfico crece.
La realidad de precios de Lambda
Lambda cobra por solicitud ($0.20 por millón) y por GB-segundo de cómputo ($0.0000166667). Para un endpoint API típico que se ejecuta por 200ms con 256MB de memoria:
- 1,000 solicitudes/día: ~$0.03/mes. Efectivamente gratis.
- 100,000 solicitudes/día: ~$3.00/mes. Todavía muy barato.
- 1,000,000 solicitudes/día: ~$30/mes. Empezando a compararse con una instancia EC2 pequeña.
- 10,000,000 solicitudes/día: ~$300/mes. Una t3.medium ($30/mes) con caché adecuado maneja esto fácilmente.
El punto de cruce depende mucho de la duración de ejecución y la asignación de memoria, pero para la mayoría de cargas de trabajo de API, Lambda deja de ser costo-eficiente en algún punto entre 1-5 millones de solicitudes por día. Por debajo de ese umbral, casi siempre es la opción más barata.
Los costos de API Gateway se acumulan
La gente olvida que las funciones Lambda detrás de API Gateway generan cargos adicionales. API Gateway cuesta $3.50 por millón de solicitudes (REST API) o $1.00 por millón (HTTP API). A escala, el costo de API Gateway excede el costo de Lambda. Si estás ejecutando suficiente tráfico para preocuparte por los costos de Lambda, deberías usar Application Load Balancer ($0.008 por LCU-hora) en lugar de API Gateway.
Fargate: el punto medio
AWS Fargate se sitúa entre Lambda y EC2 tanto en costo como en complejidad operativa. Pagas por vCPU y memoria por segundo, sin gestión de instancias. Para cargas de trabajo que necesitan ejecutarse continuamente pero no quieres gestionar servidores, Fargate con proveedores de capacidad Spot ofrece un buen equilibrio.
Una tarea de Fargate con 0.25 vCPU y 0.5GB de memoria cuesta aproximadamente $9/mes ejecutándose continuamente. Eso es competitivo con una t4g.nano y obtienes colocación automática, health checks y escalado sin gestionar el host subyacente.
Monitoreo y alertas de costos
No puedes optimizar lo que no mides. Aquí está el stack de monitoreo que configuro para cada proyecto.
AWS Cost Explorer
Activa Cost Explorer y configura un presupuesto mensual con alertas al 50%, 80% y 100% del umbral. Esto es lo mínimo. La vista "Costo por servicio" de Cost Explorer muestra inmediatamente a dónde va el dinero.
# Create a budget with email alerts
aws budgets create-budget \
--account-id 123456789012 \
--budget '{
"BudgetName": "Monthly-Total",
"BudgetLimit": {"Amount": "500", "Unit": "USD"},
"TimeUnit": "MONTHLY",
"BudgetType": "COST"
}' \
--notifications-with-subscribers '[{
"Notification": {
"NotificationType": "ACTUAL",
"ComparisonOperator": "GREATER_THAN",
"Threshold": 80,
"ThresholdType": "PERCENTAGE"
},
"Subscribers": [{
"SubscriptionType": "EMAIL",
"Address": "team@startup.com"
}]
}]'
Infracost para Infrastructure as Code
Si usas Terraform, Infracost se integra en tu pipeline de CI y muestra estimaciones de costos para cada cambio de infraestructura antes de que se aplique. Esto es transformador — cambia la conciencia de costos de una sorpresa mensual a una conversación en el pull request.
# .github/workflows/infracost.yml
name: Infracost
on: pull_request
jobs:
infracost:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Infracost
uses: infracost/actions/setup@v3
with:
api-key: ${{ secrets.INFRACOST_API_KEY }}
- name: Generate cost estimate
run: |
infracost breakdown --path=. \
--format=json --out-file=/tmp/infracost.json
infracost comment github \
--path=/tmp/infracost.json \
--repo=$GITHUB_REPOSITORY \
--pull-request=${{ github.event.pull_request.number }} \
--github-token=${{ secrets.GITHUB_TOKEN }}
Detección de anomalías de costos
AWS Cost Anomaly Detection usa machine learning para identificar patrones de gasto inusuales. Es gratuito y envía alertas cuando el gasto se desvía de los patrones históricos. Actívalo para cada servicio y configura notificaciones SNS a Slack.
Patrones arquitectónicos que ahorran dinero
Más allá de dimensionar recursos individuales correctamente, ciertas decisiones arquitectónicas cambian fundamentalmente tu estructura de costos.
Caché agresivo
Una distribución de CloudFront frente a tu API para respuestas cacheables cuesta $0.085/10,000 solicitudes HTTPS y $0.085/GB de transferencia — pero elimina esas solicitudes de llegar a tu backend. Para APIs con muchas lecturas (que son la mayoría), una tasa de acierto de caché del 90% significa que tu backend maneja 10x menos tráfico.
Aún más simple: un caché en memoria como Redis o simplemente un caché LRU local en tu aplicación puede eliminar consultas redundantes a la base de datos. He visto costos de base de datos reducirse un 60% después de agregar un caché de 15 minutos en los 5 endpoints accedidos con más frecuencia.
Usa S3 inteligentemente
S3 tiene múltiples clases de almacenamiento, y usar la correcta importa:
| Clase de almacenamiento | Costo/GB/mes | Caso de uso |
|---|---|---|
| S3 Standard | $0.023 | Datos activos, acceso frecuente |
| S3 Infrequent Access | $0.0125 | Backups, logs con más de 30 días |
| S3 Glacier Instant | $0.004 | Archivos que necesitan acceso inmediato |
| S3 Glacier Deep Archive | $0.00099 | Archivos a largo plazo, acceso raro |
Configura S3 Lifecycle Policies para transicionar objetos automáticamente entre clases de almacenamiento:
{
"Rules": [
{
"ID": "TransitionToIA",
"Status": "Enabled",
"Transitions": [
{
"Days": 30,
"StorageClass": "STANDARD_IA"
},
{
"Days": 90,
"StorageClass": "GLACIER_INSTANT_RETRIEVAL"
}
]
}
]
}
Servicios gestionados vs auto-hospedados
Este trade-off es matizado. Los servicios gestionados (RDS, ElastiCache, OpenSearch Service) cuestan más por unidad de cómputo que auto-hospedar en EC2, pero incluyen parches, backups, failover y monitoreo. Para una startup sin una persona dedicada a operaciones, el tiempo de ingeniería ahorrado casi siempre justifica la prima.
La excepción: servicios gestionados en los niveles más altos. Una instancia RDS db.r6g.2xlarge cuesta significativamente más que la instancia EC2 equivalente ejecutando PostgreSQL. Una vez que tienes un equipo capaz de operaciones y estás gastando más de $1,000/mes en un solo servicio gestionado, vale la pena evaluar el auto-hospedaje.
Consolida donde sea posible
Ejecutar instancias RDS separadas para entornos de staging, QA y desarrollo es caro. Opciones:
- Usa una sola instancia RDS con bases de datos separadas para entornos de no-producción.
- Usa Aurora Serverless v2 para dev/staging — escala a cero cuando está inactivo.
- Ejecuta bases de datos de desarrollo en una sola EC2 Spot Instance con Docker.
Un playbook real de optimización de costos
Aquí está el proceso paso a paso que sigo al emprender un proyecto de optimización de costos. Esto típicamente logra un 30-50% de ahorro dentro del primer mes.
Semana 1: Auditoría
- Activa AWS Cost Explorer si no está activo.
- Obtén un desglose de costos de 3 meses por servicio.
- Identifica los 5 servicios principales por gasto.
- Ejecuta AWS Compute Optimizer y Trusted Advisor.
- Lista todos los volúmenes EBS sin adjuntar, Elastic IPs sin usar y balanceadores de carga inactivos.
Semana 2: Ganancias rápidas
- Elimina recursos sin usar identificados en la auditoría.
- Dimensiona correctamente las instancias más sobredimensionadas (1 tamaño abajo, monitorea).
- Configura VPC endpoints para tráfico de S3 y DynamoDB.
- Activa S3 Lifecycle Policies en todos los buckets.
- Configura alertas de presupuesto.
Semana 3: Compromisos
- Analiza cargas de trabajo en estado estable para elegibilidad de Savings Plan.
- Compra Compute Savings Plans para el gasto base de cómputo.
- Compra RDS Reserved Instances para bases de datos de producción.
- Convierte cargas de trabajo adecuadas a Spot Instances.
Semana 4: Arquitectura
- Agrega capas de caché donde sea apropiado.
- Evalúa migración serverless para cargas de trabajo adecuadas.
- Consolida entornos de no-producción.
- Configura Infracost en el pipeline de CI.
- Documenta la línea base de costos para monitoreo continuo.
Qué no optimizar
La optimización de costos tiene rendimientos decrecientes, y algunos "ahorros" crean más problemas de los que resuelven.
No sacrifiques fiabilidad por costo. Ejecutar una base de datos de producción en un despliegue de una sola zona de disponibilidad para ahorrar en cargos Multi-AZ es una economía falsa. La primera caída costará más que años de primas Multi-AZ.
No optimices en exceso para la escala actual. Si tu startup está creciendo 20% mes a mes, pasar una semana optimizando un servicio de $50/mes no es un buen uso del tiempo. Enfócate en los elementos de mayor gasto.
No luches contra el modelo de precios del proveedor de nube. AWS está diseñado para ser caro si luchas contra sus convenciones. Usa servicios gestionados como están diseñados, aprovecha los niveles gratuitos y aprovecha los descuentos por compromiso que ofrecen. Intentar construir alrededor de los precios con arquitecturas demasiado ingeniosas usualmente sale contraproducente.
No elimines el monitoreo para ahorrar dinero. CloudWatch cuesta dinero, pero volar a ciegas cuesta más. Los $15/mes que gastas en monitoreo detallado te salvarán de la sorpresa de $500 que el monitoreo detallado habría detectado.
El efecto compuesto
El mayor argumento para la optimización temprana de costos no son los ahorros inmediatos — son los hábitos y la infraestructura que pones en marcha. Una startup que configura alertas de presupuesto, usa Infracost en CI y revisa costos mensualmente mantendrá infraestructura eficiente a medida que escale. Una startup que ignora los costos hasta la serie B se encontrará con facturas de AWS de $30,000/mes que toman seis meses de esfuerzo dedicado para desenredar.
Comienza con la auditoría. Los números te dirán dónde enfocarte.
Danil Ulmashev
Full Stack Developer
Interesado en trabajar juntos?