# VPC Flow Logs CloudWatch to S3

> 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.

Source: https://zop.dev/integrations/aws/recommendations/vpc-flow-logs-cloudwatch-to-s3
Updated: 2026-08-19

---

## 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](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html).
- 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](https://aws.amazon.com/cloudwatch/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

1. Create an S3 bucket (or reuse a log-archive bucket) for VPC flow logs
2. Create a new flow log on the VPC with the destination set to that S3 bucket
3. Verify flow records are landing in S3, then delete the CloudWatch Logs flow log
4. 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)
