CloudWatch Log Group Standard Class -- Use Infrequent Access
What does ZopNight detect here?
CloudWatch log groups in the Standard class with zero subscription and metric filters can move new ingestion to Infrequent Access, halving the ingest rate from $0.50 to $0.25 per GB. ZopNight measures 30-day IncomingBytes, prices savings as monthly ingested GB times the $0.25 delta, and abstains when ingestion measures zero.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1518 |
| Category | rightsizing |
| Severity | low |
| Metric | none — pure configuration read |
| Source | cloudwatch_log_class.go |
Where it applies
Standard class groups with no filters attached
- Metadata: log_class=STANDARD (provider-authoritative LogGroupClass; abstains when absent)
- Access-pattern gate: subscription_filter_count + metric_filter_count (discoverer stampLogAccessPattern); the rule fires only when both are present and zero; fail-closed on a missing probe, so IA is never recommended for a group whose real-time subscription/metric filters it would break
- Volume gate: resource.SizeGB ≥ 1, cross-checked against the harvested CWLogsStoredBytes (Maximum) so the gate still holds when SizeGB is unpopulated
Why the discount lands on ingestion, not storage
real SKU-rate delta on the harvested ingestion volume, not a storage-rate fraction. The Standard→Infrequent-Access discount applies to ingestion ($0.50 → $0.25/GB ingested, exactly 50% cheaper); IA storage is the same $0.03/GB-mo as Standard, so storage contributes $0 to the saving. monthlyIngestGB is derived from CWLogsIncomingBytes normalized to a 30-day month; savings = monthlyIngestGB × ($0.50 − $0.25). The rule concrete-or-abstains: it returns nil when the ingestion series is absent or measures zero. r.pricing[resource.UID] (from SetPricing) is the aggregator’s monthly cost for the log group (calcCloudWatchLogs). calcCloudWatchLogs adds an ingestion component only from cost-usage/CUR enrichment (Meta.LogIngestedGB>0), so for calculated-cost / non-billing-backed orgs it is effectively storage-only. CurrentCostUSD is reconciled onto a single consistent basis: it is max(aggregatorMonthlyCost, standardIngestionCost) where standardIngestionCost = monthlyIngestGB × $0.50. When the aggregator basis already includes ingestion (billing-backed) it dominates and is used as-is (and no second ingestion term is layered on, so the underlying AWS/Logs IncomingBytes metric is never double-counted); when it under-counts (storage-only), the rule’s own measured Standard ingestion bill becomes the current-cost floor. OptimizedCostUSD = CurrentCostUSD − SavingsUSD is then strictly positive, floored at monthlyIngestGB × $0.25 (the IA rate), because a class switch trims the ingestion rate and cannot zero the bill. This supersedes the prior cap-to-cost (which set savings==CurrentCostUSD → OptimizedCostUSD==$0 on storage-only orgs, implying a class switch eliminated all cost; the RC-1518 defect surfaced by the 2026-07-07 da470928 audit). A defensive savings > cost cap is retained (now unreachable, since the ingestion delta is strictly below standardIngestionCost ≤ CurrentCostUSD) to match the sibling storage-delta rules. Sub-$5 savings are dropped by the central shouldDropLowSavings floor.
Repointing the log source to a new IA group
- Note: log class cannot be changed on existing log groups
- Create a new log group with Infrequent Access class
- Update the log source to write to the new log group
- Infrequent Access supports CloudWatch Logs Insights but not real-time subscriptions
Incoming bytes, with stored bytes as a cross-check
CWLogsIncomingBytes (AWS/Logs IncomingBytes as CloudWatch Logs publishes it per group, 30d) is required, and the rule abstains if it is absent or zero; CWLogsStoredBytes (AWS/Logs StoredBytes, 30d) is the cross-check for the size gate