Skip to main content
idle · aws

SNS topics with zero publishes already cost nothing

resource types
1
rule IDs covered
1
severity
low

What does ZopNight detect here?

ZopNight's idle-SNS rule is retired in place and always abstains: SNS bills $0.50 per million publishes with no standing charge, so a topic with zero NumberOfMessagesPublished over 30 days already costs $0. A finding could never name a real saving, so the rule reports nothing instead of a $0 card.

Signal and threshold

How ZopNight evaluates SNS topics with zero publishes already cost nothing.
Field Value
Rule IDsRC-182
Categoryidle
Severitylow
Metricnone — pure configuration read
Sourcesns_idle.go

The publish gate and the cost gate exclude each other

The rule as originally specified had two conditions: the topic’s NumberOfMessagesPublished series had to sit at zero on both maximum and average across a 30-day window, and the topic had to carry a positive monthly cost. On SNS those two conditions can never be true at once.

SNS has no standing charge. Its pricing is purely per request, roughly $0.50 per million publishes, and the first million each month is free. A topic that published nothing issued no billable requests, so its cost row is either absent or $0, so the cost gate fails. A topic whose cost is positive must have had billable publishes, and the idle gate fails. No topic in any account can pass both, which means the rule was permanently unfireable in production, not merely rare.

Retired in place rather than resurrected

ZopNight’s cost rules follow a concrete-or-abstain contract: a finding filed under a cost-driven category must name a real, recoverable dollar amount, or say nothing. Deleting a topic that already bills $0 recovers $0, and there is no fallback lever: nothing to rightsize, no off-hours schedule, no commitment to re-tier. So the rule now abstains unconditionally instead of emitting a $0 card that would clutter a list people act on.

The category deliberately stays idle, the honest cost-driven label. Parking the rule under an advisory label would have let a $0 finding sneak past the low-savings filter, the exact shape the retirement removed.

The topic metric is still collected

The rule still declares NumberOfMessagesPublished, one of the topic-level series SNS reports to CloudWatch, over 30 days as a required metric. That keeps the aggregator’s fetch wiring intact: the series continues to be harvested per topic, so anything else that reads publish activity keeps working, and a future non-cost hygiene signal could be built on real data rather than a dead tag.

Reading publish activity yourself

Terminal window
aws cloudwatch get-metric-statistics \
--namespace AWS/SNS --metric-name NumberOfMessagesPublished \
--dimensions Name=TopicName,Value=my-topic \
--start-time "$(date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)" \
--end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--period 86400 --statistics Sum

An empty result or all-zero sums means nothing published in the month.

Tidying dead topics is still worthwhile

A silent topic costs nothing but can still mislead: stale subscriptions point at endpoints that no longer exist, and alarms wired to it never fire. If nothing should publish to it, review the subscription list, delete the topic, and remove any CloudWatch alarms that reference it, as hygiene, not as savings.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·