GuardDuty bills on the volume of logs it analyses, and the largest of those streams is one you did not create, cannot see, and cannot turn off independently. Disabling your own VPC Flow Logs does not reduce the bill by a cent.
What does GuardDuty charge for?
Volume, not findings. The Amazon GuardDuty pricing page states that "GuardDuty prices are based on the volume of service logs, events, workloads, or data analyzed." You are not billed per finding, per account or per Region, so a quiet account with heavy traffic costs more than a noisy one with little.
| What is analysed | Metered as |
|---|---|
| CloudTrail management events | Per million events |
| VPC Flow Logs and Route 53 Resolver DNS query logs | Per GB per month, tiered |
| S3 data events | Per million events |
| EBS volume malware scanning | Per GB scanned |
The flow log and DNS meter is tiered, with published breaks at the first 500 GB a month, the next 2,000 GB, the next 7,500 GB and over 10,000 GB. Read the current rates on the pricing page rather than from an article: they are region-specific and they change.
Why doesn't turning off flow logs reduce the bill?
Because GuardDuty never used yours. From the GuardDuty data sources documentation:
When you enable GuardDuty, it immediately starts analyzing VPC flow log data from Amazon EC2 instances within your account. GuardDuty consumes this data through an independent and duplicate stream of flow logs. You don't need to create or configure VPC flow logs in your account for GuardDuty to access this data. This process does not affect any of your existing flow logs configuration.
Read that as a billing statement and it says something uncomfortable. There are two flow log streams over the same traffic. You pay CloudWatch Vended Logs ingestion on the one you configured, and you pay GuardDuty per GB on the one it created. Deleting your flow logs removes the first charge and leaves the second untouched, because the streams are independent by design.
Which means GuardDuty cost is a function of your network traffic volume, and the only real levers on it are the traffic itself and the Regions and accounts where GuardDuty is enabled. There is no sampling setting, no aggregation interval, and no field selection. The levers that work on your own flow logs do not exist here.
One extension of the same behaviour worth knowing if you run Lambda: "Lambda Network Activity Monitoring includes Amazon VPC flow logs from all Lambda functions for your account, even those logs that don't use VPC networking." Functions with no VPC configuration still generate analysed volume.
Does the free trial hide the real number?
It does, and this is the most common way GuardDuty surprises an account. The pricing page states that "GuardDuty comes with a 30-day trial on the AWS Free Tier for accounts that have never enabled the service before", that "This free trial applies to each new AWS account in each Region", and that "Malware Protection for Amazon EBS is included in the GuardDuty free trial, while Malware Protection for Amazon S3 has a free tier without a trial period."
Per account, per Region. Enable GuardDuty organisation-wide across twelve Regions and every account-Region pair starts its own trial clock. The bill arrives later, all at once, and it looks like a sudden increase rather than the end of a trial. The console shows a projected monthly cost during the trial: read it before the trial ends, on the accounts and Regions with real traffic, not on the test account.
Should you enable it in every Region?
The security argument says yes, because an attacker will use the Region you are not watching. The cost consequence is that Regions with no workloads still analyse CloudTrail management events, which are global in effect and continuous. That is usually small, and it is not zero. Which findings each data source can produce is listed in the GuardDuty finding types reference.
What is not small is a Region carrying real traffic, because flow log volume scales with it. Before enabling broadly, price the traffic you already know about:
aws ec2 describe-regions --query 'Regions[].RegionName' --output text | tr '\t' '\n' | \
while read r; do
n=$(aws ec2 describe-instances --region "$r" \
--filters Name=instance-state-name,Values=running \
--query 'length(Reservations[].Instances[])' --output text 2>/dev/null)
[ "$n" != "0" ] && echo "$r running instances: $n"
done
The full list of what GuardDuty can analyse, including the optional protection plans that add meters, is in the GuardDuty protection plans documentation, and multi-account enablement is covered under managing GuardDuty with AWS Organizations.
Regions with running instances are the ones that will generate analysed GB. Regions with none still bill for management event analysis and are cheap to cover, which is the usual reason to enable everywhere anyway.
Which Region is your GuardDuty spend in?
It appears under its own service name, so usage type is the dimension that separates the four meters:
aws ce get-cost-and-usage \
--time-period Start=2026-07-01,End=2026-08-01 \
--granularity MONTHLY \
--metrics UnblendedCost UsageQuantity \
--group-by Type=DIMENSION,Key=USAGE_TYPE \
--group-by Type=DIMENSION,Key=REGION \
--filter '{"Dimensions":{"Key":"SERVICE","Values":["Amazon GuardDuty"]}}'
Grouping by Region as well as usage type is the part that matters, because the answer is nearly always concentrated in one or two Regions and the fix is traffic-side rather than GuardDuty-side.
Two things this will not tell you. GuardDuty is not covered by Cost Optimization Hub, which generates no recommendations for it, so nothing will ever flag a Region you enabled and forgot. And because the charge tracks traffic volume rather than configuration, a cost anomaly monitor is a better fit than a budget: a traffic change moves this line with no deployment behind it.
How does this compare to paying for the logs yourself?
It is worth setting the two side by side, because teams often assume GuardDuty replaces flow logs and it does not.
| Your VPC Flow Logs | GuardDuty's stream | |
|---|---|---|
| Who creates it | You | GuardDuty, automatically |
| Can you read the records | Yes | No |
| Volume levers | Aggregation interval, custom format, filtered subnets | None |
| Billed as | CloudWatch Vended Logs ingestion, or S3 delivery | GuardDuty per GB analysed |
| Turning the other one off | Removes this charge | Changes nothing here |
So they are complements, not alternatives. You keep your own flow logs when you need to query what actually traversed the network, which GuardDuty cannot give you, and you accept the GuardDuty meter as the price of detection. What you should not do is keep a high-volume flow log configuration you never query on the assumption that GuardDuty depends on it. It does not.
And if the flow logs you do keep are landing in CloudWatch, the log class you chose changes their cost by half: what CloudWatch Logs actually cost.