This finding is distinct from idle Lambda functions, which flag functions with zero invocations. An idle Lambda may still have a log group with no retention policy — and vice versa: a log group with unbounded retention may belong to an actively invoked function.
What Parsivex checks: a CloudWatch log group set to Never Expire with at least 1 GB of stored data and created more than 30 days ago.
What setting retention does: a retention policy prunes log events older than the configured window going forward. It does not immediately delete existing stored data. To reclaim storage from data already on disk, you may need a separate one-time cleanup after setting retention.
Remediation default: scripts use a 90-day retention period as a balance between operational debugging and storage savings. Compliance, audit, or security log groups often need longer retention — adjust before applying.
What triggers this finding
A CloudWatch log group with retention set to "Never Expire", allowing log data to accumulate indefinitely.
Typical fix
Set a retention period (e.g. 30, 90, or 365 days) appropriate for compliance and debugging needs.
Example savings
Varies by ingestion volume — high-traffic log groups can cost $10–$500+/month without retention.
See also: Severity and savings estimates for how Parsivex calculates figures on your report.
Ingestion versus storage on your bill
CloudWatch Logs charges twice for the same data, and only one of the two charges is what this finding is about. Ingestion is billed once, per GB, at the moment events arrive — that is the larger line item for a chatty application, and no retention setting will reduce it. Archival storage is billed per GB every month for as long as the data exists, at $0.03 per GB-month in us-east-1, which is the rate Parsivex applies to the stored size AWS reports for the group.
That is why the dollar figure on this finding often looks small next to what CloudWatch costs you overall. The number is a monthly annuity, not a one-off. A group holding 40 GB with no expiry is roughly $1.20 every month, forever, and it grows every month the application keeps writing. The stored size AWS reports is also compressed and includes per-event metadata, so the raw log volume behind a 40 GB figure is considerably larger than 40 GB.
Parsivex applies the standard-class archival rate uniformly. It does not distinguish the Standard and Infrequent Access log classes, and it reads at most 2,000 log groups per account per scan, so very large estates may have more never-expire groups than the report shows.
Finding never-expire groups from the CLI
One call lists every group that would qualify, sorted by what it is costing you:
aws logs describe-log-groups \
--query 'reverse(sort_by(logGroups[?retentionInDays == `null` && storedBytes > `1073741824`], &storedBytes))[].[logGroupName,storedBytes]' \
--output table
retentionInDays is absent — not zero — when a group never expires, which is why the query compares against null. The byte threshold is the same 1 GB floor Parsivex uses.
In the console, open CloudWatch → Log groups, add the Stored bytes column, and sort descending. Groups with Never expire in the Retention column and a meaningful size are the same set.
When never-expire is the right setting
Unbounded retention is a deliberate, correct choice more often than most cost tools admit:
- Audit and security trails. CloudTrail management events, VPC flow logs feeding an investigation workflow, GuardDuty and WAF logs — regulatory or contractual retention can run to seven years, and a 90-day policy would destroy the evidence you are required to keep.
- Groups that are already tiered elsewhere. If a subscription filter ships events to S3, OpenSearch, or a third-party SIEM, CloudWatch is a buffer and short retention is right — but confirm the export is healthy before you cut, because the export is now your system of record.
- Low-volume groups you will never notice. Below the 1 GB floor Parsivex stays quiet on purpose; a never-expire group holding 200 MB costs under a cent a month and is not worth a change ticket.
What setting retention actually deletes
put-retention-policy is a single call and the setting itself is reversible in seconds. The data loss it triggers is not.
aws logs put-retention-policy --log-group-name /aws/lambda/checkout --retention-in-days 90
Once the policy applies, AWS deletes events older than the window — typically within 72 hours — and there is no undelete. Setting 90 days on a group holding three years of audit history discards everything beyond the window permanently. Storage charges also do not fall the instant you apply the policy; billing follows the actual deletion.
If the data has any chance of mattering, export before you prune. aws logs create-export-task writes the group to S3, where the same bytes cost a fraction of CloudWatch's rate and can move to Glacier from there. Export first, verify the objects landed, then set retention — the sequence costs one extra day and makes the change reversible.