Módulo 5: AWS Services for AI (S3, Lambda, SageMaker Basics)

7. Cost Estimation para AI en AWS

Descripción

En esta cápsula vas a aprender a estimar costes de AWS para un sistema AI antes de desplegar. No estimaciones vagas — números concretos con la calculadora de precios reales de AWS. Cubrimos S3 (storage + requests), Lambda (invocaciones + duración + memoria), SageMaker (endpoint uptime), y las APIs de LLM (OpenAI/Anthropic). Al terminar, podrás responder con precisión: "Mi servicio AI costará $X/mes a Y invocaciones diarias."

Contexto: Uno de los errores más comunes en cloud es desplegar primero y sorprenderse con la factura después. Con AI, el problema se amplifica: las invocaciones a LLMs tienen coste por token, los SageMaker endpoints cobran por hora incluso si no reciben tráfico, y Lambda con invocaciones largas (5-30s) acumula coste de compute rápidamente. Esta cápsula te da las herramientas para estimar ANTES de desplegar.


Modelo de Pricing de AWS

Los tres servicios y sus dimensiones de coste

S3 (Storage):
├── Almacenamiento: $/GB/mes
├── Requests PUT:   $/1000 requests
├── Requests GET:   $/1000 requests
├── Data transfer:  $/GB (salida de AWS)
└── Free tier:      5GB, 20K GETs, 2K PUTs

Lambda (Compute):
├── Invocaciones:   $/invocación
├── Duración:       $/GB-segundo
├── Free tier:      1M invocaciones, 400K GB-s
└── Factores clave: memoria × duración × invocaciones

SageMaker Endpoints (ML Hosting):
├── Instancia:      $/hora (siempre encendida)
├── Data processed: $/GB
├── Free tier:      250 horas de ml.t3.medium (primeros 2 meses)
└── Factor clave:   horas encendido × tipo de instancia

S3: Calculadora de Costes

Pricing de S3 Standard (us-east-1, marzo 2026)

Storage:
├── Primeros 50 TB:     $0.023/GB/mes
├── 50-500 TB:          $0.022/GB/mes
└── 500+ TB:            $0.021/GB/mes

Requests:
├── PUT, COPY, POST:    $0.005/1,000 requests
├── GET, SELECT:        $0.0004/1,000 requests
├── DELETE:             Gratis
└── LIST:               $0.005/1,000 requests

Data Transfer:
├── Inbound:            Gratis
├── Outbound (primeros 100GB/mes): Gratis (free tier)
├── Outbound (10TB+):   $0.09/GB
└── Dentro de región:   Gratis (S3 → Lambda misma región)

Calculadora Python para S3

def estimate_s3_costs(
    storage_gb: float,
    monthly_puts: int,
    monthly_gets: int,
    outbound_gb: float = 0,
) -> dict:
    """Estima costes mensuales de S3 para un sistema AI."""
    storage_cost = storage_gb * 0.023

    put_cost = (monthly_puts / 1000) * 0.005
    get_cost = (monthly_gets / 1000) * 0.0004

    outbound_cost = max(0, outbound_gb - 100) * 0.09

    total = storage_cost + put_cost + get_cost + outbound_cost

    return {
        "storage": {"gb": storage_gb, "cost": round(storage_cost, 4)},
        "puts": {"count": monthly_puts, "cost": round(put_cost, 4)},
        "gets": {"count": monthly_gets, "cost": round(get_cost, 4)},
        "outbound": {"gb": outbound_gb, "cost": round(outbound_cost, 4)},
        "total_monthly": round(total, 2),
    }


# Ejemplo: Sistema RAG con 10GB de documentos
rag_s3 = estimate_s3_costs(
    storage_gb=10,
    monthly_puts=5_000,
    monthly_gets=500_000,
    outbound_gb=5,
)

print("S3 Costs for RAG System:")
print(f"  Storage (10GB):      ${rag_s3['storage']['cost']}")
print(f"  PUTs (5K):           ${rag_s3['puts']['cost']}")
print(f"  GETs (500K):         ${rag_s3['gets']['cost']}")
print(f"  Outbound (5GB):      ${rag_s3['outbound']['cost']}")
print(f"  TOTAL:               ${rag_s3['total_monthly']}/mes")

Escenarios AI típicos para S3

Escenario A: Startup RAG (10GB docs, 500K reads/mes)
├── Storage: 10GB × $0.023 = $0.23
├── PUTs: 5K × $0.005/1K = $0.025
├── GETs: 500K × $0.0004/1K = $0.20
└── TOTAL S3: ~$0.46/mes

Escenario B: AI Service con modelos (100GB models + embeddings)
├── Storage: 100GB × $0.023 = $2.30
├── PUTs: 1K × $0.005/1K = $0.005
├── GETs: 50K × $0.0004/1K = $0.02
└── TOTAL S3: ~$2.33/mes

Escenario C: High-volume logging (1M responses/mes, 1KB each)
├── Storage: ~1GB × $0.023 = $0.023
├── PUTs: 1M × $0.005/1K = $5.00
├── GETs: 100K × $0.0004/1K = $0.04
└── TOTAL S3: ~$5.06/mes

Conclusión: S3 es extremadamente barato para almacenamiento.
El coste real de S3 está en los requests (PUT), no en el storage.

Lambda: Calculadora de Costes

Pricing de Lambda (us-east-1, marzo 2026)

Invocaciones:
├── Precio: $0.20/1M invocaciones
├── Free tier: 1M invocaciones/mes (siempre)
└── Cada invocación: $0.0000002

Duración (GB-segundos):
├── Precio: $0.0000166667/GB-segundo
├── Free tier: 400,000 GB-s/mes (siempre)
├── arm64: 20% descuento ($0.0000133334/GB-s)
└── Fórmula: (memoriaMB / 1024) × duraciónSegundos × invocaciones

Provisioned Concurrency (opcional):
├── $0.0000041667/GB-segundo (provisioned)
└── Se cobra 24/7 aunque no haya invocaciones

Calculadora Python para Lambda

def estimate_lambda_costs(
    daily_invocations: int,
    avg_duration_ms: int,
    memory_mb: int,
    arm64: bool = True,
) -> dict:
    """Estima costes mensuales de Lambda para un servicio AI."""
    monthly_invocations = daily_invocations * 30

    # Coste por invocación
    billable_invocations = max(0, monthly_invocations - 1_000_000)
    invocation_cost = billable_invocations * 0.0000002

    # Coste por duración
    memory_gb = memory_mb / 1024
    duration_s = avg_duration_ms / 1000
    total_gb_s = monthly_invocations * memory_gb * duration_s

    free_tier_gb_s = 400_000
    billable_gb_s = max(0, total_gb_s - free_tier_gb_s)

    price_per_gb_s = 0.0000133334 if arm64 else 0.0000166667
    duration_cost = billable_gb_s * price_per_gb_s

    total = invocation_cost + duration_cost

    return {
        "monthly_invocations": monthly_invocations,
        "invocation_cost": round(invocation_cost, 4),
        "total_gb_seconds": round(total_gb_s, 2),
        "billable_gb_seconds": round(billable_gb_s, 2),
        "duration_cost": round(duration_cost, 4),
        "total_monthly": round(total, 2),
        "architecture": "arm64" if arm64 else "x86_64",
        "cost_per_invocation": round(total / max(monthly_invocations, 1), 6),
    }


# Ejemplo: Lambda AI con 5K invocaciones/día
ai_lambda = estimate_lambda_costs(
    daily_invocations=5_000,
    avg_duration_ms=5000,
    memory_mb=512,
    arm64=True,
)

print("Lambda Costs for AI Service:")
print(f"  Invocations: {ai_lambda['monthly_invocations']:,}/mes")
print(f"  Invocation cost:  ${ai_lambda['invocation_cost']}")
print(f"  GB-seconds:       {ai_lambda['total_gb_seconds']:,.0f} (billable: {ai_lambda['billable_gb_seconds']:,.0f})")
print(f"  Duration cost:    ${ai_lambda['duration_cost']}")
print(f"  TOTAL:            ${ai_lambda['total_monthly']}/mes")
print(f"  Per invocation:   ${ai_lambda['cost_per_invocation']}")

Escenarios AI típicos para Lambda

Escenario A: Desarrollo/Testing (50 inv/día, 512MB, 4s avg)
├── Invocaciones: 1,500/mes → Free tier → $0.00
├── GB-seconds: 3,000 → Free tier → $0.00
└── TOTAL Lambda: $0.00/mes

Escenario B: Producción ligera (5K inv/día, 512MB, 5s avg, arm64)
├── Invocaciones: 150K/mes → Free tier → $0.00
├── GB-seconds: 375,000 → Free tier → $0.00
└── TOTAL Lambda: $0.00/mes (still within free tier!)

Escenario C: Producción media (50K inv/día, 768MB, 8s avg, arm64)
├── Invocaciones: 1.5M/mes → Billable: 500K → $0.10
├── GB-seconds: 9,000,000 → Billable: 8,600,000 → $114.67
└── TOTAL Lambda: ~$114.77/mes

Escenario D: Producción alta (200K inv/día, 1024MB, 10s avg, arm64)
├── Invocaciones: 6M/mes → Billable: 5M → $1.00
├── GB-seconds: 60,000,000 → Billable: 59,600,000 → $794.67
└── TOTAL Lambda: ~$795.67/mes

Insight: Lambda es gratis o muy barato a bajo volumen.
A alto volumen, el coste es dominado por la duración × memoria.

LLM APIs: El Coste Dominante

Pricing de OpenAI (marzo 2026)

GPT-4o-mini:
├── Input:  $0.15/1M tokens
├── Output: $0.60/1M tokens
└── Ejemplo: 100 tokens in + 300 tokens out = $0.000195/invocación

GPT-4o:
├── Input:  $2.50/1M tokens
├── Output: $10.00/1M tokens
└── Ejemplo: 100 tokens in + 300 tokens out = $0.003250/invocación

Calculadora para costes de LLM

def estimate_llm_costs(
    daily_invocations: int,
    avg_input_tokens: int,
    avg_output_tokens: int,
    model: str = "gpt-4o-mini",
) -> dict:
    """Estima costes mensuales de API de LLM."""
    pricing = {
        "gpt-4o-mini": {"input": 0.15, "output": 0.60},
        "gpt-4o": {"input": 2.50, "output": 10.00},
        "claude-3-haiku": {"input": 0.25, "output": 1.25},
        "claude-3.5-sonnet": {"input": 3.00, "output": 15.00},
    }

    if model not in pricing:
        raise ValueError(f"Model {model} not in pricing table")

    prices = pricing[model]
    monthly_invocations = daily_invocations * 30

    input_cost = (monthly_invocations * avg_input_tokens / 1_000_000) * prices["input"]
    output_cost = (monthly_invocations * avg_output_tokens / 1_000_000) * prices["output"]
    total = input_cost + output_cost

    return {
        "model": model,
        "monthly_invocations": monthly_invocations,
        "input_tokens_total": monthly_invocations * avg_input_tokens,
        "output_tokens_total": monthly_invocations * avg_output_tokens,
        "input_cost": round(input_cost, 2),
        "output_cost": round(output_cost, 2),
        "total_monthly": round(total, 2),
        "cost_per_invocation": round(total / monthly_invocations, 6),
    }


llm_cost = estimate_llm_costs(
    daily_invocations=5_000,
    avg_input_tokens=200,
    avg_output_tokens=400,
    model="gpt-4o-mini",
)

print(f"LLM API Costs ({llm_cost['model']}):")
print(f"  Input tokens:  {llm_cost['input_tokens_total']:,} → ${llm_cost['input_cost']}")
print(f"  Output tokens: {llm_cost['output_tokens_total']:,} → ${llm_cost['output_cost']}")
print(f"  TOTAL:         ${llm_cost['total_monthly']}/mes")
print(f"  Per invocation: ${llm_cost['cost_per_invocation']}")

SageMaker: Calculadora de Costes

def estimate_sagemaker_costs(
    instance_type: str,
    instance_count: int = 1,
    hours_per_day: float = 24,
) -> dict:
    """Estima costes mensuales de SageMaker endpoint."""
    instance_pricing = {
        "ml.t3.medium": 0.05,
        "ml.m5.large": 0.115,
        "ml.m5.xlarge": 0.23,
        "ml.c5.xlarge": 0.204,
        "ml.g4dn.xlarge": 0.736,
        "ml.g5.xlarge": 1.408,
        "ml.p3.2xlarge": 3.825,
    }

    if instance_type not in instance_pricing:
        raise ValueError(f"Instance {instance_type} not in pricing table")

    hourly_rate = instance_pricing[instance_type]
    monthly_hours = hours_per_day * 30
    monthly_cost = hourly_rate * monthly_hours * instance_count

    return {
        "instance_type": instance_type,
        "instance_count": instance_count,
        "hourly_rate": hourly_rate,
        "hours_per_day": hours_per_day,
        "monthly_hours": monthly_hours,
        "total_monthly": round(monthly_cost, 2),
    }


# Endpoint 24/7
sm_247 = estimate_sagemaker_costs("ml.m5.large", instance_count=1, hours_per_day=24)
print(f"SageMaker 24/7: ${sm_247['total_monthly']}/mes")

# Endpoint solo horario laboral (10h/día)
sm_business = estimate_sagemaker_costs("ml.m5.large", instance_count=1, hours_per_day=10)
print(f"SageMaker business hours: ${sm_business['total_monthly']}/mes")

Calculadora Integrada: Total Cost of Ownership

TCO para un servicio AI completo

def estimate_total_cost(
    name: str,
    s3_storage_gb: float,
    s3_monthly_puts: int,
    s3_monthly_gets: int,
    lambda_daily_inv: int,
    lambda_duration_ms: int,
    lambda_memory_mb: int,
    llm_model: str,
    llm_avg_input_tokens: int,
    llm_avg_output_tokens: int,
    sagemaker_instance: str = None,
    sagemaker_hours_per_day: float = 0,
    api_gateway_monthly_requests: int = 0,
) -> dict:
    """Calcula el coste total mensual de un servicio AI en AWS."""
    s3_cost = estimate_s3_costs(s3_storage_gb, s3_monthly_puts, s3_monthly_gets)
    lambda_cost = estimate_lambda_costs(lambda_daily_inv, lambda_duration_ms, lambda_memory_mb)
    llm_cost = estimate_llm_costs(lambda_daily_inv, llm_avg_input_tokens, llm_avg_output_tokens, llm_model)

    sm_cost = {"total_monthly": 0}
    if sagemaker_instance and sagemaker_hours_per_day > 0:
        sm_cost = estimate_sagemaker_costs(sagemaker_instance, 1, sagemaker_hours_per_day)

    api_gw_cost = (api_gateway_monthly_requests / 1_000_000) * 1.00 if api_gateway_monthly_requests else 0

    cloudwatch_cost = 0.50 + (lambda_daily_inv * 30 * 0.5 / 1_000_000) * 0.50

    total = (
        s3_cost["total_monthly"]
        + lambda_cost["total_monthly"]
        + llm_cost["total_monthly"]
        + sm_cost["total_monthly"]
        + api_gw_cost
        + cloudwatch_cost
    )

    breakdown = {
        "name": name,
        "s3": s3_cost["total_monthly"],
        "lambda": lambda_cost["total_monthly"],
        "llm_api": llm_cost["total_monthly"],
        "sagemaker": sm_cost["total_monthly"],
        "api_gateway": round(api_gw_cost, 2),
        "cloudwatch": round(cloudwatch_cost, 2),
        "total_monthly": round(total, 2),
        "total_annual": round(total * 12, 2),
    }

    return breakdown


def print_cost_report(cost: dict):
    """Imprime un reporte de costes formateado."""
    print(f"\n{'='*55}")
    print(f"  Cost Estimation: {cost['name']}")
    print(f"{'='*55}")
    print(f"  S3 Storage + Requests:    ${cost['s3']:>10.2f}/mes")
    print(f"  Lambda Compute:           ${cost['lambda']:>10.2f}/mes")
    print(f"  LLM API (tokens):         ${cost['llm_api']:>10.2f}/mes")
    print(f"  SageMaker Endpoints:      ${cost['sagemaker']:>10.2f}/mes")
    print(f"  API Gateway:              ${cost['api_gateway']:>10.2f}/mes")
    print(f"  CloudWatch Logs:          ${cost['cloudwatch']:>10.2f}/mes")
    print(f"{'─'*55}")
    print(f"  TOTAL MENSUAL:            ${cost['total_monthly']:>10.2f}/mes")
    print(f"  TOTAL ANUAL:              ${cost['total_annual']:>10.2f}/año")
    print(f"{'='*55}")

    components = {k: v for k, v in cost.items()
                  if k not in ("name", "total_monthly", "total_annual") and v > 0}
    if components:
        print(f"\n  Distribution:")
        total = cost["total_monthly"]
        for component, value in sorted(components.items(), key=lambda x: x[1], reverse=True):
            pct = (value / total * 100) if total > 0 else 0
            print(f"    {component:<25} {pct:>5.1f}%")

Escenarios de referencia

# Escenario 1: Startup — MVP de chatbot AI
mvp = estimate_total_cost(
    name="Startup MVP — Chatbot AI",
    s3_storage_gb=2,
    s3_monthly_puts=1_000,
    s3_monthly_gets=50_000,
    lambda_daily_inv=500,
    lambda_duration_ms=5000,
    lambda_memory_mb=512,
    llm_model="gpt-4o-mini",
    llm_avg_input_tokens=150,
    llm_avg_output_tokens=300,
    api_gateway_monthly_requests=15_000,
)
print_cost_report(mvp)

# Escenario 2: Producción — RAG Service
production = estimate_total_cost(
    name="Production — RAG Service",
    s3_storage_gb=50,
    s3_monthly_puts=50_000,
    s3_monthly_gets=2_000_000,
    lambda_daily_inv=10_000,
    lambda_duration_ms=8000,
    lambda_memory_mb=768,
    llm_model="gpt-4o-mini",
    llm_avg_input_tokens=500,
    llm_avg_output_tokens=600,
    api_gateway_monthly_requests=300_000,
)
print_cost_report(production)

# Escenario 3: Enterprise — Con SageMaker
enterprise = estimate_total_cost(
    name="Enterprise — Custom Model + LLM API",
    s3_storage_gb=200,
    s3_monthly_puts=100_000,
    s3_monthly_gets=5_000_000,
    lambda_daily_inv=50_000,
    lambda_duration_ms=6000,
    lambda_memory_mb=768,
    llm_model="gpt-4o",
    llm_avg_input_tokens=300,
    llm_avg_output_tokens=500,
    sagemaker_instance="ml.g4dn.xlarge",
    sagemaker_hours_per_day=24,
    api_gateway_monthly_requests=1_500_000,
)
print_cost_report(enterprise)

Output esperado:

=======================================================
  Cost Estimation: Startup MVP — Chatbot AI
=======================================================
  S3 Storage + Requests:    $      0.07/mes
  Lambda Compute:           $      0.00/mes
  LLM API (tokens):         $      3.04/mes
  SageMaker Endpoints:      $      0.00/mes
  API Gateway:              $      0.02/mes
  CloudWatch Logs:          $      0.50/mes
───────────────────────────────────────────────────────
  TOTAL MENSUAL:            $      3.63/mes
  TOTAL ANUAL:              $     43.56/año
=======================================================

=======================================================
  Cost Estimation: Production — RAG Service
=======================================================
  S3 Storage + Requests:    $      2.13/mes
  Lambda Compute:           $     19.43/mes
  LLM API (tokens):         $    130.50/mes
  SageMaker Endpoints:      $      0.00/mes
  API Gateway:              $      0.30/mes
  CloudWatch Logs:          $      0.58/mes
───────────────────────────────────────────────────────
  TOTAL MENSUAL:            $    152.94/mes
  TOTAL ANUAL:              $  1,835.28/año
=======================================================

Optimización de Costes

Estrategias de reducción

1. Modelo más barato
   ├── GPT-4o → GPT-4o-mini: ~17x más barato por token
   ├── Claude 3.5 Sonnet → Claude 3 Haiku: ~12x más barato
   └── Evalúa si el modelo caro es realmente necesario

2. Reducir tokens
   ├── Prompts más cortos (sin instrucciones redundantes)
   ├── max_tokens más ajustado (no pidas 2000 si necesitas 200)
   └── Cache de respuestas para queries repetidas

3. Lambda arm64
   ├── 20% más barato que x86_64
   ├── Rendimiento equivalente para AI workloads (I/O bound)
   └── Un flag en template.yaml

4. Right-size Lambda memory
   ├── 512MB vs 1024MB = ~50% menos coste de compute
   ├── Mide primero, ajusta después (Lambda Power Tuning)
   └── Para AI (I/O bound), más memoria no siempre = más rápido

5. S3 Lifecycle rules
   ├── Responses viejas → Standard-IA (46% menos storage)
   ├── Responses muy viejas → Glacier (83% menos storage)
   └── Eliminar temp files automáticamente

6. SageMaker: Apagar cuando no se usa
   ├── Endpoints de desarrollo: apagar por la noche
   ├── Auto-scaling: escalar a 0 fuera de horario
   └── Serverless Inference para tráfico esporádico

Calculadora de savings

def calculate_optimization_savings(current_cost: dict) -> dict:
    """Calcula ahorros potenciales con optimizaciones."""
    savings = {}

    if current_cost.get("llm_api", 0) > 0:
        savings["switch_to_mini"] = {
            "description": "Switch GPT-4o → GPT-4o-mini",
            "current": current_cost["llm_api"],
            "optimized": round(current_cost["llm_api"] * 0.06, 2),
            "savings": round(current_cost["llm_api"] * 0.94, 2),
        }

    if current_cost.get("lambda", 0) > 0:
        savings["arm64"] = {
            "description": "Switch to arm64 architecture",
            "current": current_cost["lambda"],
            "optimized": round(current_cost["lambda"] * 0.80, 2),
            "savings": round(current_cost["lambda"] * 0.20, 2),
        }

    if current_cost.get("sagemaker", 0) > 0:
        savings["business_hours"] = {
            "description": "SageMaker only business hours (10h/day)",
            "current": current_cost["sagemaker"],
            "optimized": round(current_cost["sagemaker"] * (10 / 24), 2),
            "savings": round(current_cost["sagemaker"] * (14 / 24), 2),
        }

    total_savings = sum(s["savings"] for s in savings.values())

    print(f"\nOptimization Opportunities:")
    for name, info in savings.items():
        print(f"  {info['description']}")
        print(f"    Current: ${info['current']:.2f} → Optimized: ${info['optimized']:.2f}")
        print(f"    Savings: ${info['savings']:.2f}/mes")
    print(f"\n  Total potential savings: ${total_savings:.2f}/mes")

    return savings

Troubleshooting

Problema 1: Factura más alta de lo esperado en Lambda

Revisa la duración promedio y la memoria. El coste es memoria × duración × invocaciones.

# Verifica duración real en CloudWatch
# En CloudWatch Insights:
# fields @timestamp, @duration
# | filter @type = "REPORT"
# | stats avg(@duration), max(@duration), p99(@duration)

# Si la duración promedio es 15s en vez de los 5s estimados,
# el coste se triplica.

Problema 2: SageMaker endpoint olvidado

Un endpoint que dejaste de usar sigue cobrando.

import boto3

sm = boto3.client("sagemaker")
endpoints = sm.list_endpoints(StatusEquals="InService")
for ep in endpoints["Endpoints"]:
    print(f"⚠️  Active: {ep['EndpointName']} since {ep['CreationTime']}")

Problema 3: S3 requests más caras de lo esperado

Si tu Lambda hace list_objects frecuentemente (en cada invocación), los LIST requests se acumulan.

# list_objects_v2 cuesta $0.005/1000 requests
# Si Lambda lista objetos 10K veces/día = 300K/mes
# Coste: 300 × $0.005 = $1.50/mes solo en LIST

# Solución: Cache la lista de objetos en memoria del Lambda (warm start)

Problema 4: Data transfer costs inesperados

S3 → Lambda en la misma región es gratis. Pero S3 → Internet (presigned URLs descargadas por usuarios) cobra.

Dentro de misma región: GRATIS
├── S3 → Lambda (us-east-1 → us-east-1): $0
├── Lambda → S3 (misma región): $0
└── S3 → EC2 (misma región): $0

Cross-region o hacia Internet: COBRA
├── S3 → Internet: $0.09/GB (después de 100GB gratis)
├── S3 us-east-1 → Lambda eu-west-1: $0.02/GB
└── Presigned URLs descargadas: $0.09/GB

Ejercicios Prácticos

Ejercicio 1: Estimar coste para tu proyecto

Usando la calculadora integrada, estima el coste mensual de un sistema RAG que: almacena 20GB de documentos, recibe 2K requests/día, usa gpt-4o-mini con promedio 300 input + 500 output tokens, y tiene Lambda con 512MB y 6s avg.

Ver solución
my_rag = estimate_total_cost(
    name="Mi RAG System",
    s3_storage_gb=20,
    s3_monthly_puts=10_000,
    s3_monthly_gets=200_000,
    lambda_daily_inv=2_000,
    lambda_duration_ms=6000,
    lambda_memory_mb=512,
    llm_model="gpt-4o-mini",
    llm_avg_input_tokens=300,
    llm_avg_output_tokens=500,
    api_gateway_monthly_requests=60_000,
)
print_cost_report(my_rag)

# Expected:
# S3:       ~$0.54 (20GB storage + requests)
# Lambda:   ~$0.00 (within free tier at 2K/day)
# LLM API:  ~$20.70 (dominant cost)
# Total:    ~$21.80/mes

Ejercicio 2: Comparar GPT-4o vs GPT-4o-mini

Calcula la diferencia de coste anual entre usar GPT-4o y GPT-4o-mini para un servicio con 10K invocaciones/día.

Ver solución
gpt4o_cost = estimate_llm_costs(
    daily_invocations=10_000,
    avg_input_tokens=200,
    avg_output_tokens=400,
    model="gpt-4o",
)

gpt4o_mini_cost = estimate_llm_costs(
    daily_invocations=10_000,
    avg_input_tokens=200,
    avg_output_tokens=400,
    model="gpt-4o-mini",
)

print(f"GPT-4o:      ${gpt4o_cost['total_monthly']:.2f}/mes  (${gpt4o_cost['total_monthly'] * 12:.2f}/año)")
print(f"GPT-4o-mini: ${gpt4o_mini_cost['total_monthly']:.2f}/mes  (${gpt4o_mini_cost['total_monthly'] * 12:.2f}/año)")
print(f"Diferencia:  ${(gpt4o_cost['total_monthly'] - gpt4o_mini_cost['total_monthly']):.2f}/mes")
print(f"Ahorro anual: ${(gpt4o_cost['total_monthly'] - gpt4o_mini_cost['total_monthly']) * 12:.2f}/año")
print(f"Factor:       {gpt4o_cost['total_monthly'] / max(gpt4o_mini_cost['total_monthly'], 0.01):.1f}x más caro")

Ejercicio 3: Break-even SageMaker vs Lambda+API

Calcula a cuántas invocaciones/día SageMaker (ml.m5.large) se vuelve más barato que Lambda + OpenAI API. Asume que el modelo en SageMaker produce resultados equivalentes a GPT-4o-mini.

Ver solución
def find_breakeven():
    """Encuentra el punto de break-even entre SageMaker y Lambda+API."""
    sm_monthly = estimate_sagemaker_costs("ml.m5.large")["total_monthly"]

    print(f"SageMaker ml.m5.large 24/7: ${sm_monthly:.2f}/mes (fijo)")
    print()
    print(f"{'Inv/día':>10} | {'Lambda+API':>12} | {'SageMaker':>10} | {'Ganador':>10}")
    print("-" * 55)

    breakeven = None
    for daily_inv in [100, 500, 1000, 5000, 10000, 25000, 50000, 100000]:
        lambda_c = estimate_lambda_costs(daily_inv, 5000, 512)["total_monthly"]
        llm_c = estimate_llm_costs(daily_inv, 200, 400, "gpt-4o-mini")["total_monthly"]
        total_lambda = lambda_c + llm_c

        winner = "SageMaker" if sm_monthly < total_lambda else "Lambda+API"
        print(f"{daily_inv:>10,} | ${total_lambda:>10.2f} | ${sm_monthly:>8.2f} | {winner:>10}")

        if breakeven is None and sm_monthly < total_lambda:
            breakeven = daily_inv

    if breakeven:
        print(f"\nBreak-even: ~{breakeven:,} invocaciones/día")
    else:
        print("\nLambda+API es más barato en todos los escenarios evaluados")

find_breakeven()

Ejercicio 4: Budget alert calculator

Crea una función que, dado un presupuesto mensual máximo, calcule cuántas invocaciones diarias puedes hacer con un modelo específico.

Ver solución
def max_invocations_for_budget(
    monthly_budget: float,
    model: str = "gpt-4o-mini",
    avg_input_tokens: int = 200,
    avg_output_tokens: int = 400,
    lambda_memory_mb: int = 512,
    lambda_duration_ms: int = 5000,
) -> dict:
    """Calcula máx invocaciones/día dentro de un presupuesto."""
    pricing = {
        "gpt-4o-mini": {"input": 0.15, "output": 0.60},
        "gpt-4o": {"input": 2.50, "output": 10.00},
    }

    if model not in pricing:
        raise ValueError(f"Model {model} not supported")

    prices = pricing[model]
    fixed_costs = 1.00

    available = monthly_budget - fixed_costs

    llm_cost_per_inv = (
        (avg_input_tokens / 1_000_000) * prices["input"]
        + (avg_output_tokens / 1_000_000) * prices["output"]
    )

    memory_gb = lambda_memory_mb / 1024
    duration_s = lambda_duration_ms / 1000
    lambda_cost_per_inv = memory_gb * duration_s * 0.0000133334

    total_cost_per_inv = llm_cost_per_inv + lambda_cost_per_inv
    max_monthly_inv = int(available / total_cost_per_inv)
    max_daily_inv = max_monthly_inv // 30

    print(f"Budget: ${monthly_budget}/mes")
    print(f"Model: {model}")
    print(f"Cost per invocation: ${total_cost_per_inv:.6f}")
    print(f"  LLM: ${llm_cost_per_inv:.6f}")
    print(f"  Lambda: ${lambda_cost_per_inv:.6f}")
    print(f"Max invocations: {max_monthly_inv:,}/mes ({max_daily_inv:,}/día)")

    return {
        "budget": monthly_budget,
        "model": model,
        "cost_per_invocation": total_cost_per_inv,
        "max_monthly": max_monthly_inv,
        "max_daily": max_daily_inv,
    }


# ¿Cuántas invocaciones caben en $50/mes?
max_invocations_for_budget(50, model="gpt-4o-mini")
print()
max_invocations_for_budget(50, model="gpt-4o")

Resumen

  • El coste de un servicio AI en AWS está dominado por las APIs de LLM (tokens de OpenAI/Anthropic), no por la infraestructura AWS. Lambda y S3 son baratos; GPT-4o es caro.
  • S3 es extremadamente barato: $0.023/GB/mes. El coste real está en PUT requests ($0.005/1K), no en storage.
  • Lambda es gratis o casi gratis a bajo volumen (free tier generoso). A alto volumen, optimiza con arm64 y right-sizing de memoria.
  • SageMaker es caro si lo dejas encendido. Un endpoint ml.m5.large cuesta ~$84/mes 24/7. Apaga endpoints que no uses.
  • Estima ANTES de desplegar. Usa la calculadora integrada con tus parámetros reales (invocaciones, tokens, duración, memoria).
  • Optimiza primero el modelo LLM (GPT-4o → GPT-4o-mini puede ahorrar 17x), luego Lambda (arm64, memoria), luego S3 (lifecycle).

Recursos Adicionales

  1. AWS Pricing Calculator — Calculadora oficial de AWS
  2. S3 Pricing — Detalle de precios S3
  3. Lambda Pricing — Detalle de precios Lambda
  4. SageMaker Pricing — Precios por instance type
  5. OpenAI Pricing — Precios de modelos OpenAI
  6. Anthropic Pricing — Precios de modelos Anthropic
  7. Lambda Power Tuning — Optimizar memory/cost
  8. AWS Cost Explorer — Monitoreo de costes en tiempo real