Difficulty: Easy
Description
We detected WAF Web ACLs in your account that send logs to CloudWatch Logs instead of S3. Vended logs delivery to S3 is approximately 50% cheaper than CloudWatch Logs, and S3 storage costs are also significantly lower. Switching the log destination to S3 can reduce both delivery and storage costs.
Selection Criteria
The WAF Web ACL has logging enabled
The log destination is CloudWatch Logs
Expected Savings
Around 50% on ingestion plus ~23% on storage, with much deeper savings if S3 lifecycle policies transition older logs to Glacier tiers.
Cost components affected:
Component | CloudWatch Logs | S3 |
Vended logs delivery (first 10 TB) | $0.50 / GB | ~$0.25 / GB |
Storage | $0.03 / GB-month | $0.023 / GB-month (Standard) |
Long-term retention | $0.03 / GB-month (flat) | Down to $0.004/GB (Glacier Deep Archive) |
Example — a WAF Web ACL generating 200 GB/month of vended logs:
Before: 200 GB × $0.50 + 200 GB × $0.03 = $106/month
After: 200 GB × $0.25 + 200 GB × $0.023 = $54.60/month
Savings: ~$51.40/month (~49%) per Web ACL, before any additional S3 lifecycle optimization
Operational Impact
Downtime: None — but note that a WAF Web ACL accepts only one logging destination at a time, so the destination must be switched in place via
wafv2:PutLoggingConfiguration. The switch is near-instant; a brief gap of a few seconds is possible during the update.Breaking changes: Any downstream consumer reading from the CloudWatch log group (subscription filters, metric filters, Logs Insights saved queries, third-party SIEMs) must be migrated to read from S3 (Athena, S3 Select, or a Lambda processor), or routed through Kinesis Firehose if near-real-time delivery is required.
Recovery: Re-pointing the destination back to the CloudWatch log group via
wafv2:PutLoggingConfigurationrestores the previous behavior. Existing CloudWatch logs are not deleted by the change.⚠️ Warning — Bucket naming: WAF requires the destination S3 bucket name to start with
aws-waf-logs-. Existing buckets that don't follow this convention cannot be used.⚠️ Warning — Real-time use cases: CloudWatch Logs offers near-real-time ingestion. If alerts depend on this latency, either accept S3 latency or use Kinesis Firehose with S3 as the destination.
⚠️ Warning — Retention & compliance: Configure S3 bucket policy, encryption (SSE-S3 or SSE-KMS), lifecycle, and Object Lock as needed to meet the same governance previously provided by the CloudWatch log group retention policy.
