VPC Flow Logs CloudWatch to S3
What does ZopNight detect here?
VPC Flow Logs delivered to CloudWatch Logs pay $0.50 per GB, while S3 delivery costs $0.25 plus roughly $0.023 in storage. ZopNight measures each VPC's flow-log ingestion from IncomingBytes, fires only above 1 GB per month, and prices the destination switch as that per-GB delivery-rate delta.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-055 |
| Category | rightsizing |
| Severity | low |
| Metric | none — pure configuration read |
| Source | vpc_flowlogs.go |
Where it applies
Flow logs still delivering to CloudWatch Logs
- flow_log_destination Metadata (VPC ec2:DescribeFlowLogs → LogDestinationType): gates on cloud-watch-logs, one of the destinations flow logs support.
- flow_log_log_group Metadata (VPC ec2:DescribeFlowLogs → LogGroupName, stamped only for an ACTIVE CloudWatch destination): the RC-1308-style join key the aggregator uses to harvest per-VPC ingestion.
- VPCFlowLogIncomingBytes metric series (aggregator service.go case vpc): AWS/Logs IncomingBytes (per-hour Sum) for the flow log’s log group, dimensioned by LogGroupName sourced from flow_log_log_group (DimSourceMetadata) and stamped under the VPC UID.
The vended-logs delivery rate delta
The savings figure is concrete (2026-07-01 repricing corrects a fabricated-savings defect in the 2026-06-30 producer-enablement). VPC Flow Logs are billed as CloudWatch vended logs: delivery is billed even when the destination is S3, because the vended-logs delivery rate is destination-dependent, not a CloudWatch-only ingestion charge that S3 delivery avoids entirely. The saving is the real vended-logs delivery-rate delta on the measured per-VPC flow-log ingestion volume: monthlyGB = Σ(IncomingBytes hourly Sum slots) / 1e9 / windowDays × 30 SavingsUSD = (cwIngestionRatePerGB 0.50 − (s3DeliveryRatePerGB 0.25 + s3StorageRatePerGB 0.023)) × monthlyGB CurrentCost = 0.50 × monthlyGB OptimizedCost = (0.25 + 0.023) × monthlyGB (= Current − Savings) Per AWS CloudWatch Logs pricing (first-10TB vended-logs tier, us-east-1), delivery to CloudWatch Logs is $0.50/GB while delivery to S3 (or Kinesis Data Firehose) is $0.25/GB, plus S3 Standard storage (~$0.023/GB-mo) on top. Moving the destination from CloudWatch Logs to S3 saves the $0.50→$0.25 delivery-rate delta, a real but partial reduction, not a drop to storage-only cost. The rule is concrete or it abstains: it fires only when the harvested ingestion series proves a positive monthly volume (≥1 GB/mo). It abstains (returns nil) for an S3 destination (already optimal), an absent destination (no flow log), or a missing/zero ingestion series (no join key on the VPC, e.g. S3 destination, where per-VPC GB is not separable from CW Logs IncomingBytes). It never emits SavingsUSD=0 under a cost concern.
Switching the destination to S3
- Create an S3 bucket (or reuse a log-archive bucket) for VPC flow logs
- Create a new flow log on the VPC with the destination set to that S3 bucket
- Verify flow records are landing in S3, then delete the CloudWatch Logs flow log
- Query S3-delivered flow logs with Amazon Athena (CloudWatch Logs Insights is not available on S3)
The ingestion volume series, per VPC
VPCFlowLogIncomingBytes (AWS/Logs IncomingBytes, Sum, 30d)