Module 5: AWS Services for AI (S3, Lambda, SageMaker Basics)
7. Cost Estimation for AI on AWS
Overview
In this capsule you'll learn to estimate AWS costs for an AI system before deploying. No vague estimates — concrete numbers with a calculator using real AWS prices. We cover S3 (storage + requests), Lambda (invocations + duration + memory), SageMaker (endpoint uptime), and the LLM APIs (OpenAI/Anthropic). By the end, you'll be able to answer precisely: "My AI service will cost $X/month at Y daily invocations."
Context: One of the most common mistakes in the cloud is deploying first and being surprised by the bill later. With AI, the problem is amplified: LLM invocations have a per-token cost, SageMaker endpoints charge by the hour even if they receive no traffic, and Lambda with long invocations (5-30s) accumulates compute cost quickly. This capsule gives you the tools to estimate BEFORE deploying.
AWS Pricing Model
The three services and their cost dimensions
S3 (Storage):
├── Storage: $/GB/month
├── PUT requests: $/1000 requests
├── GET requests: $/1000 requests
├── Data transfer: $/GB (outbound from AWS)
└── Free tier: 5GB, 20K GETs, 2K PUTs
Lambda (Compute):
├── Invocations: $/invocation
├── Duration: $/GB-second
├── Free tier: 1M invocations, 400K GB-s
└── Key factors: memory × duration × invocations
SageMaker Endpoints (ML Hosting):
├── Instance: $/hour (always on)
├── Data processed: $/GB
├── Free tier: 250 hours of ml.t3.medium (first 2 months)
└── Key factor: hours on × instance type
S3: Cost Calculator
S3 Standard pricing (us-east-1, March 2026)
Storage:
├── First 50 TB: $0.023/GB/month
├── 50-500 TB: $0.022/GB/month
└── 500+ TB: $0.021/GB/month
Requests:
├── PUT, COPY, POST: $0.005/1,000 requests
├── GET, SELECT: $0.0004/1,000 requests
├── DELETE: Free
└── LIST: $0.005/1,000 requests
Data Transfer:
├── Inbound: Free
├── Outbound (first 100GB/month): Free (free tier)
├── Outbound (10TB+): $0.09/GB
└── Within region: Free (S3 → Lambda same region)
Python calculator for S3
def estimate_s3_costs(
storage_gb: float,
monthly_puts: int,
monthly_gets: int,
outbound_gb: float = 0,
) -> dict:
"""Estimates monthly S3 costs for an AI system."""
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),
}
# Example: RAG system with 10GB of documents
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']}/month")
Typical AI scenarios for S3
Scenario A: RAG startup (10GB docs, 500K reads/month)
├── Storage: 10GB × $0.023 = $0.23
├── PUTs: 5K × $0.005/1K = $0.025
├── GETs: 500K × $0.0004/1K = $0.20
└── TOTAL S3: ~$0.46/month
Scenario B: AI Service with models (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/month
Scenario C: High-volume logging (1M responses/month, 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/month
Conclusion: S3 is extremely cheap for storage.
The real S3 cost is in the requests (PUT), not in the storage.
Lambda: Cost Calculator
Lambda pricing (us-east-1, March 2026)
Invocations:
├── Price: $0.20/1M invocations
├── Free tier: 1M invocations/month (always)
└── Each invocation: $0.0000002
Duration (GB-seconds):
├── Price: $0.0000166667/GB-second
├── Free tier: 400,000 GB-s/month (always)
├── arm64: 20% discount ($0.0000133334/GB-s)
└── Formula: (memoryMB / 1024) × durationSeconds × invocations
Provisioned Concurrency (optional):
├── $0.0000041667/GB-second (provisioned)
└── Charged 24/7 even if there are no invocations
Python calculator for Lambda
def estimate_lambda_costs(
daily_invocations: int,
avg_duration_ms: int,
memory_mb: int,
arm64: bool = True,
) -> dict:
"""Estimates monthly Lambda costs for an AI service."""
monthly_invocations = daily_invocations * 30
# Cost per invocation
billable_invocations = max(0, monthly_invocations - 1_000_000)
invocation_cost = billable_invocations * 0.0000002
# Cost per duration
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),
}
# Example: AI Lambda with 5K invocations/day
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']:,}/month")
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']}/month")
print(f" Per invocation: ${ai_lambda['cost_per_invocation']}")
Typical AI scenarios for Lambda
Scenario A: Development/Testing (50 inv/day, 512MB, 4s avg)
├── Invocations: 1,500/month → Free tier → $0.00
├── GB-seconds: 3,000 → Free tier → $0.00
└── TOTAL Lambda: $0.00/month
Scenario B: Light production (5K inv/day, 512MB, 5s avg, arm64)
├── Invocations: 150K/month → Free tier → $0.00
├── GB-seconds: 375,000 → Free tier → $0.00
└── TOTAL Lambda: $0.00/month (still within free tier!)
Scenario C: Medium production (50K inv/day, 768MB, 8s avg, arm64)
├── Invocations: 1.5M/month → Billable: 500K → $0.10
├── GB-seconds: 9,000,000 → Billable: 8,600,000 → $114.67
└── TOTAL Lambda: ~$114.77/month
Scenario D: High production (200K inv/day, 1024MB, 10s avg, arm64)
├── Invocations: 6M/month → Billable: 5M → $1.00
├── GB-seconds: 60,000,000 → Billable: 59,600,000 → $794.67
└── TOTAL Lambda: ~$795.67/month
Insight: Lambda is free or very cheap at low volume.
At high volume, the cost is dominated by duration × memory.
LLM APIs: The Dominant Cost
OpenAI pricing (March 2026)
GPT-4o-mini:
├── Input: $0.15/1M tokens
├── Output: $0.60/1M tokens
└── Example: 100 tokens in + 300 tokens out = $0.000195/invocation
GPT-4o:
├── Input: $2.50/1M tokens
├── Output: $10.00/1M tokens
└── Example: 100 tokens in + 300 tokens out = $0.003250/invocation
Calculator for LLM costs
def estimate_llm_costs(
daily_invocations: int,
avg_input_tokens: int,
avg_output_tokens: int,
model: str = "gpt-4o-mini",
) -> dict:
"""Estimates monthly LLM API costs."""
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']}/month")
print(f" Per invocation: ${llm_cost['cost_per_invocation']}")
SageMaker: Cost Calculator
def estimate_sagemaker_costs(
instance_type: str,
instance_count: int = 1,
hours_per_day: float = 24,
) -> dict:
"""Estimates monthly SageMaker endpoint costs."""
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']}/month")
# Endpoint only during business hours (10h/day)
sm_business = estimate_sagemaker_costs("ml.m5.large", instance_count=1, hours_per_day=10)
print(f"SageMaker business hours: ${sm_business['total_monthly']}/month")
Integrated Calculator: Total Cost of Ownership
TCO for a complete AI service
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:
"""Calculates the total monthly cost of an AI service on 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):
"""Prints a formatted cost report."""
print(f"\n{'='*55}")
print(f" Cost Estimation: {cost['name']}")
print(f"{'='*55}")
print(f" S3 Storage + Requests: ${cost['s3']:>10.2f}/month")
print(f" Lambda Compute: ${cost['lambda']:>10.2f}/month")
print(f" LLM API (tokens): ${cost['llm_api']:>10.2f}/month")
print(f" SageMaker Endpoints: ${cost['sagemaker']:>10.2f}/month")
print(f" API Gateway: ${cost['api_gateway']:>10.2f}/month")
print(f" CloudWatch Logs: ${cost['cloudwatch']:>10.2f}/month")
print(f"{'─'*55}")
print(f" TOTAL MONTHLY: ${cost['total_monthly']:>10.2f}/month")
print(f" TOTAL ANNUAL: ${cost['total_annual']:>10.2f}/year")
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}%")
Reference scenarios
# Scenario 1: Startup — AI chatbot MVP
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)
# Scenario 2: Production — 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)
# Scenario 3: Enterprise — With 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)
Expected output:
=======================================================
Cost Estimation: Startup MVP — Chatbot AI
=======================================================
S3 Storage + Requests: $ 0.07/month
Lambda Compute: $ 0.00/month
LLM API (tokens): $ 3.04/month
SageMaker Endpoints: $ 0.00/month
API Gateway: $ 0.01/month
CloudWatch Logs: $ 0.50/month
───────────────────────────────────────────────────────
TOTAL MONTHLY: $ 3.63/month
TOTAL ANNUAL: $ 43.55/year
=======================================================
=======================================================
Cost Estimation: Production — RAG Service
=======================================================
S3 Storage + Requests: $ 2.20/month
Lambda Compute: $ 18.67/month
LLM API (tokens): $ 130.50/month
SageMaker Endpoints: $ 0.00/month
API Gateway: $ 0.30/month
CloudWatch Logs: $ 0.57/month
───────────────────────────────────────────────────────
TOTAL MONTHLY: $ 152.25/month
TOTAL ANNUAL: $ 1826.94/year
=======================================================
Cost Optimization
Reduction strategies
1. Cheaper model
├── GPT-4o → GPT-4o-mini: ~17x cheaper per token
├── Claude 3.5 Sonnet → Claude 3 Haiku: ~12x cheaper
└── Evaluate whether the expensive model is really necessary
2. Reduce tokens
├── Shorter prompts (no redundant instructions)
├── Tighter max_tokens (don't ask for 2000 if you need 200)
└── Cache responses for repeated queries
3. Lambda arm64
├── 20% cheaper than x86_64
├── Equivalent performance for AI workloads (I/O bound)
└── A single flag in template.yaml
4. Right-size Lambda memory
├── 512MB vs 1024MB = ~50% less compute cost
├── Measure first, adjust later (Lambda Power Tuning)
└── For AI (I/O bound), more memory doesn't always = faster
5. S3 Lifecycle rules
├── Old responses → Standard-IA (46% less storage)
├── Very old responses → Glacier (83% less storage)
└── Delete temp files automatically
6. SageMaker: Turn off when not in use
├── Development endpoints: shut down at night
├── Auto-scaling: scale to 0 outside hours
└── Serverless Inference for sporadic traffic
Savings calculator
def calculate_optimization_savings(current_cost: dict) -> dict:
"""Calculates potential savings from optimizations."""
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}/month")
print(f"\n Total potential savings: ${total_savings:.2f}/month")
return savings
Troubleshooting
Problem 1: Higher-than-expected Lambda bill
Check the average duration and memory. The cost is memory × duration × invocations.
# Check the real duration in CloudWatch
# In CloudWatch Insights:
# fields @timestamp, @duration
# | filter @type = "REPORT"
# | stats avg(@duration), max(@duration), p99(@duration)
# If the average duration is 15s instead of the estimated 5s,
# the cost triples.
Problem 2: Forgotten SageMaker endpoint
An endpoint you stopped using keeps charging.
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']}")
Problem 3: More expensive S3 requests than expected
If your Lambda calls list_objects frequently (on every invocation), the LIST requests add up.
# list_objects_v2 costs $0.005/1000 requests
# If Lambda lists objects 10K times/day = 300K/month
# Cost: 300 × $0.005 = $1.50/month just in LIST
# Solution: Cache the object list in the Lambda's memory (warm start)
Problem 4: Unexpected data transfer costs
S3 → Lambda in the same region is free. But S3 → Internet (presigned URLs downloaded by users) charges.
Within the same region: FREE
├── S3 → Lambda (us-east-1 → us-east-1): $0
├── Lambda → S3 (same region): $0
└── S3 → EC2 (same region): $0
Cross-region or to the Internet: CHARGES
├── S3 → Internet: $0.09/GB (after 100GB free)
├── S3 us-east-1 → Lambda eu-west-1: $0.02/GB
└── Downloaded presigned URLs: $0.09/GB
Practical Exercises
Exercise 1: Estimate the cost for your project
Using the integrated calculator, estimate the monthly cost of a RAG system that: stores 20GB of documents, receives 2K requests/day, uses gpt-4o-mini with an average of 300 input + 500 output tokens, and has a Lambda with 512MB and 6s avg.
See solution
my_rag = estimate_total_cost(
name="My 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.59 (20GB storage + requests)
# Lambda: ~$0.00 (within free tier at 2K/day)
# LLM API: ~$20.70 (dominant cost)
# Total: ~$21.86/month
Exercise 2: Compare GPT-4o vs GPT-4o-mini
Calculate the annual cost difference between using GPT-4o and GPT-4o-mini for a service with 10K invocations/day.
See solution
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}/month (${gpt4o_cost['total_monthly'] * 12:.2f}/year)")
print(f"GPT-4o-mini: ${gpt4o_mini_cost['total_monthly']:.2f}/month (${gpt4o_mini_cost['total_monthly'] * 12:.2f}/year)")
print(f"Difference: ${(gpt4o_cost['total_monthly'] - gpt4o_mini_cost['total_monthly']):.2f}/month")
print(f"Annual savings: ${(gpt4o_cost['total_monthly'] - gpt4o_mini_cost['total_monthly']) * 12:.2f}/year")
print(f"Factor: {gpt4o_cost['total_monthly'] / max(gpt4o_mini_cost['total_monthly'], 0.01):.1f}x more expensive")
Exercise 3: Break-even SageMaker vs Lambda+API
Calculate at how many invocations/day SageMaker (ml.m5.large) becomes cheaper than Lambda + OpenAI API. Assume the SageMaker model produces results equivalent to GPT-4o-mini.
See solution
def find_breakeven():
"""Finds the break-even point between SageMaker and Lambda+API."""
sm_monthly = estimate_sagemaker_costs("ml.m5.large")["total_monthly"]
print(f"SageMaker ml.m5.large 24/7: ${sm_monthly:.2f}/month (fixed)")
print()
print(f"{'Inv/day':>10} | {'Lambda+API':>12} | {'SageMaker':>10} | {'Winner':>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:,} invocations/day")
else:
print("\nLambda+API is cheaper in all evaluated scenarios")
find_breakeven()
Exercise 4: Budget alert calculator
Create a function that, given a maximum monthly budget, calculates how many daily invocations you can make with a specific model.
See solution
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:
"""Calculates the max invocations/day within a budget."""
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}/month")
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:,}/month ({max_daily_inv:,}/day)")
return {
"budget": monthly_budget,
"model": model,
"cost_per_invocation": total_cost_per_inv,
"max_monthly": max_monthly_inv,
"max_daily": max_daily_inv,
}
# How many invocations fit in $50/month?
max_invocations_for_budget(50, model="gpt-4o-mini")
print()
max_invocations_for_budget(50, model="gpt-4o")
Summary
- The cost of an AI service on AWS is dominated by the LLM APIs (OpenAI/Anthropic tokens), not by the AWS infrastructure. Lambda and S3 are cheap; GPT-4o is expensive.
- S3 is extremely cheap: $0.023/GB/month. The real cost is in PUT requests ($0.005/1K), not in storage.
- Lambda is free or almost free at low volume (generous free tier). At high volume, optimize with arm64 and memory right-sizing.
- SageMaker is expensive if you leave it on. An ml.m5.large endpoint costs ~$84/month 24/7. Turn off endpoints you don't use.
- Estimate BEFORE deploying. Use the integrated calculator with your real parameters (invocations, tokens, duration, memory).
- Optimize the LLM model first (GPT-4o → GPT-4o-mini can save 17x), then Lambda (arm64, memory), then S3 (lifecycle).
Additional Resources
- AWS Pricing Calculator — Official AWS calculator
- S3 Pricing — S3 price details
- Lambda Pricing — Lambda price details
- SageMaker Pricing — Prices by instance type
- OpenAI Pricing — OpenAI model prices
- Anthropic Pricing — Anthropic model prices
- Lambda Power Tuning — Optimize memory/cost
- AWS Cost Explorer — Real-time cost monitoring