CloudWatch Logs Are Eating Your Budget: A Cost Optimization Guide

40 min read

CloudWatch is one of the sneakiest AWS cost drivers. Learn about log ingestion, retention, and cross-region transfer costs—plus how to cut them by 50-80%.

AWS CloudWatch cost-optimization logging

CloudWatch Logs Are Eating Your Budget

The silent cost driver nobody warned you about

$0.50/GB
Log Ingestion
$0.03/GB
Storage/Month
50-80%
Potential Savings

You set up CloudWatch logging because that's what AWS recommends. You enabled it on your Lambda functions, ECS containers, and EC2 instances. Three months later, your CloudWatch bill is higher than your compute costs—and you're not even reading those logs.

CloudWatch Logs is deceptively expensive. The costs seem small (fractions of pennies), but at scale, they compound into one of the largest line items on your AWS bill.

The Math That Hurts

CloudWatch Pricing Breakdown

Log Ingestion $0.50/GB
Every byte you send to CloudWatch
Log Storage $0.03/GB/month
Accumulates if no retention policy
Log Insights Queries $0.005/GB scanned
Per query across log data
Cross-Region Transfer $0.02/GB
If you centralize logs

Real-World Example

A typical microservices application:
10 services × 100MB logs/day 1GB/day
Monthly ingestion (30GB) $15.00
After 1 year storage (365GB) $10.95/month
Queries (50GB scanned/month) $0.25
Year 1 Total $311.20
At 10x scale (100 services):
$3,112/year → $25,940/year by year 3

The Compounding Problem

Without Retention Policies, Costs Compound

Time Logs Stored Storage Cost + Ingestion Total Monthly
Month 1 30GB $0.90 $15.00 $15.90
Month 6 180GB $5.40 $15.00 $20.40
Month 12 365GB $10.95 $15.00 $25.95
Month 24 730GB $21.90 $15.00 $36.90
Month 36 1,095GB $32.85 $15.00 $47.85
Without retention:
$959 over 3 years
And growing every month
With 30-day retention:
$573 over 3 years
40% savings, flat cost

5 Strategies to Cut CloudWatch Costs

1

Set Retention Policies on All Log Groups

This is the single most impactful change. Most logs are only useful for debugging recent issues.

Recommended Retention

Development/Test: 3-7 days
Production (non-critical): 14-30 days
Production (critical): 30-90 days
Audit/Compliance: 1-7 years (use S3)

Set via AWS CLI

aws logs put-retention-policy \
  --log-group-name /aws/lambda/my-function \
  --retention-in-days 14
Savings: 50-90% on storage costs
2

Filter Before Ingestion

Not all logs need to go to CloudWatch. Filter out noise at the source to reduce ingestion costs.

Don't Log

  • • Health check responses
  • • Successful 200s at INFO level
  • • Debug statements in prod
  • • Redundant correlation IDs

Log Selectively

  • • Errors and warnings
  • • Request summaries
  • • Key business events
  • • Performance outliers

Always Log

  • • Authentication events
  • • Authorization failures
  • • System errors
  • • Audit trail events

Lambda Example: Change Log Level

# Set environment variable in Lambda
LOG_LEVEL=WARN # Only log warnings and errors

# Or configure in code
logging.getLogger().setLevel(logging.WARNING)
Can reduce log volume by 80-95%
3

Export Old Logs to S3

For long-term retention, S3 is 10x cheaper than CloudWatch storage.

Cost Comparison

CloudWatch Storage
$0.03/GB/month
S3 Standard
$0.023/GB/month
S3 Glacier
$0.004/GB/month
87% cheaper!

Export Strategy

1 Keep last 14-30 days in CloudWatch for active debugging
2 Export to S3 daily using subscription filter or scheduled export
3 Use S3 Lifecycle to move to Glacier after 90 days
4 Use Athena for querying S3 logs when needed
4

Use CloudWatch Log Classes

AWS introduced Infrequent Access log class—50% cheaper ingestion for logs you rarely query.

Standard Class

Ingestion: $0.50/GB
Storage: $0.03/GB/month
Best for: Frequently queried logs

Infrequent Access Class

Ingestion: $0.25/GB (50% off!)
Storage: $0.03/GB/month
Best for: Archive/compliance logs

Create Infrequent Access log group:

aws logs create-log-group \
  --log-group-name /aws/lambda/my-archive-logs \
  --log-group-class INFREQUENT_ACCESS
5

Consolidate Log Groups

Having thousands of small log groups increases management overhead and can lead to unmanaged retention policies.

Before: Log Group Sprawl

/aws/lambda/api-handler-1
/aws/lambda/api-handler-2
/aws/lambda/api-handler-3
/aws/lambda/worker-1
/aws/lambda/worker-2
... (200+ log groups)
Problem: Hard to manage retention

After: Organized Hierarchy

/prod/api/handlers
/prod/workers
/staging/api/handlers
/dev/all
Easier to set retention by environment

Common CloudWatch Cost Culprits

Lambda Functions

  • ! Default: Log every invocation at INFO level
  • ! Nested JSON objects bloat log size
  • ! No default retention policy
  • Fix: Set LOG_LEVEL=WARN and 7-day retention

ECS/Fargate

  • ! Container stdout/stderr goes to CloudWatch
  • ! Multi-line stack traces multiply log size
  • ! Health check logs are noisy
  • Fix: Configure awslogs-datetime-format

API Gateway

  • ! Execution logs include full request/response
  • ! Access logs for every request
  • ! High-traffic APIs = high log volume
  • Fix: Disable execution logs in prod, sample access logs

VPC Flow Logs

  • ! Log every network packet metadata
  • ! Busy VPCs generate GB/hour
  • ! Often enabled and forgotten
  • Fix: Send to S3 instead of CloudWatch

Quick CloudWatch Audit

Run these commands to assess your CloudWatch costs:

1. Find log groups without retention policies:

aws logs describe-log-groups --query 'logGroups[?!retentionInDays].[logGroupName,storedBytes]' --output table

2. Find largest log groups by storage:

aws logs describe-log-groups --query 'sort_by(logGroups, &storedBytes)[-10:].[logGroupName,storedBytes]' --output table

3. Find log groups with most ingestion (last 24h):

aws cloudwatch get-metric-statistics --namespace AWS/Logs --metric-name IncomingBytes \
  --dimensions Name=LogGroupName,Value=YOUR_LOG_GROUP \
  --start-time $(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 86400 --statistics Sum

4. Set 14-day retention on all log groups at once:

for lg in $(aws logs describe-log-groups --query 'logGroups[?!retentionInDays].logGroupName' --output text); do
  aws logs put-retention-policy --log-group-name "$lg" --retention-in-days 14
done

See How Much CloudWatch Is Costing You

Upload your AWS Cost Explorer CSV to see a detailed breakdown of your CloudWatch costs and other optimization opportunities.

Analyze My CloudWatch Costs Free

No credit card required • Instant breakdown • 100% free

The Bottom Line

CloudWatch Logs is a useful service, but its default settings are expensive. The key is to be intentional: decide what you actually need to log, how long you need to keep it, and where the cheapest place to store it is.

50-80%
Potential cost reduction
30 Min
To audit and fix
Immediate
Impact on next bill