Introduction to SNS Monitoring
Amazon Simple Notification Service (SNS) is a fully managed pub/sub messaging service that decouples producers and consumers. While SNS handles message routing, delivery, and retries automatically, monitoring its behavior is essential. SNS publishes native metrics to Amazon CloudWatch, giving you visibility into message volumes, delivery success rates, and failure patterns. By combining these metrics with CloudWatch Alarms and Dashboards, you build a comprehensive observability layer that surfaces anomalies before they impact downstream systems.
Monitoring SNS means tracking three interconnected layers: metrics—the raw numerical data points that describe your topics and subscriptions; alarms—threshold-based rules that trigger notifications or automated actions when metrics deviate; and dashboards—visual canvases that aggregate graphs, alarms, and key indicators into a single pane of glass. This tutorial walks through each layer with practical code examples you can run against your own AWS account.
Why SNS Monitoring Matters
SNS often sits in the critical path of event-driven architectures. A silent failure in an SNS topic can mean dropped orders, missed alerts, or stalled workflows. Monitoring matters for several concrete reasons:
- Delivery guarantees are probabilistic—SNS retries failed deliveries, but a persistent failure to deliver to a Lambda or HTTP endpoint indicates a downstream problem that needs human attention.
- Message volume anomalies—a sudden spike may signal a bug in an upstream publisher, while a sharp drop could mean a configuration change blocked traffic.
- Cost and quota awareness—SNS topics have quotas for throughput and size. Monitoring helps you stay within limits and forecast capacity needs.
- Compliance and auditing—you can prove message delivery SLAs and demonstrate operational excellence with historical metric data.
- Multi-subscription drift—one failing subscription (e.g., an email endpoint) does not affect others, but without monitoring, you might never notice the dead letter queue filling up.
Key SNS Metrics in CloudWatch
SNS emits metrics in the AWS/SNS namespace. Some metrics apply to the entire topic, while others are scoped to individual subscriptions. Understanding the distinction is crucial for building precise alarms.
Topic-Level Metrics
Topic-level metrics aggregate across all subscriptions and provide a high-level view of publish activity. The most important ones are:
NumberOfMessagesPublished— total messages published to the topic (sum over a period).NumberOfNotificationsDelivered— total successful deliveries to all subscriptions.NumberOfNotificationsFailed— total failed deliveries across subscriptions.PublishSize— the size in bytes of messages published (useful for tracking payload bloat).SMSMonthToDateSpending— only for SMS topics; tracks MTD cost.
These metrics are available in 1-minute granularity by default. You can enable detailed monitoring for 1-second granularity at a higher cost.
Subscription-Level Metrics
Subscription metrics are published under the same namespace but include a SubscriptionId dimension. They let you pinpoint exactly which subscriber is experiencing problems:
NumberOfNotificationsDelivered(per subscription)NumberOfNotificationsFailed(per subscription)NumberOfNotificationsFilteredOut— messages that matched a filter policy and were skipped (helpful for debugging filter rules).NumberOfNotificationsFilteredOutInvalidAttributes— messages that failed filter evaluation due to malformed attributes.
To retrieve subscription-level metrics, you need the subscription ARN or the automatically assigned subscription ID. You can list subscriptions via the SNS API or the AWS CLI.
Setting Up CloudWatch Alarms for SNS
Alarms evaluate a metric against a threshold over a specified number of evaluation periods. When the condition is met, the alarm transitions to ALARM state and can publish to an SNS topic (creating a "meta-alarm" pattern) or invoke actions via composite alarms. Below are practical examples for common SNS alarm scenarios.
Alarm 1: Detect Delivery Failure Rate Spike
This alarm triggers when the percentage of failed deliveries exceeds 5% over a 5-minute window, sustained for two consecutive periods.
aws cloudwatch put-metric-alarm \
--alarm-name "sns-high-delivery-failure-rate" \
--alarm-description "Triggers when SNS delivery failure rate exceeds 5%" \
--namespace "AWS/SNS" \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:ops-alerts" \
--metric-name "NumberOfNotificationsFailed" \
--statistic "Sum" \
--period 300 \
--evaluation-periods 2 \
--threshold 0 \
--comparison-operator "GreaterThanThreshold" \
--treat-missing-data "notBreaching" \
--dimensions "Name=TopicName,Value=order-events" \
--unit "Count"
For a rate-based alarm, combine two metrics using CloudWatch Metric Math. The CLI supports metric math via the --metrics parameter:
aws cloudwatch put-metric-alarm \
--alarm-name "sns-failure-rate-percent" \
--alarm-description "Alert when failed deliveries exceed 5% of total deliveries" \
--namespace "AWS/SNS" \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:ops-alerts" \
--evaluation-periods 2 \
--threshold 5 \
--comparison-operator "GreaterThanThreshold" \
--treat-missing-data "notBreaching" \
--metrics '[{
"Id": "failed",
"MetricStat": {
"Metric": { "Namespace": "AWS/SNS", "MetricName": "NumberOfNotificationsFailed", "Dimensions": [{ "Name": "TopicName", "Value": "order-events" }] },
"Stat": "Sum",
"Period": 300
},
"ReturnData": false
}, {
"Id": "delivered",
"MetricStat": {
"Metric": { "Namespace": "AWS/SNS", "MetricName": "NumberOfNotificationsDelivered", "Dimensions": [{ "Name": "TopicName", "Value": "order-events" }] },
"Stat": "Sum",
"Period": 300
},
"ReturnData": false
}, {
"Id": "percent",
"Expression": "(failed / (failed + delivered)) * 100",
"Label": "FailureRatePercent",
"ReturnData": true
}]'
Alarm 2: Low Message Volume (Potential Producer Outage)
Detect a sudden drop in published messages—indicating an upstream producer may be down:
aws cloudwatch put-metric-alarm \
--alarm-name "sns-low-publish-volume" \
--alarm-description "Triggers when messages published drop below 10 per minute" \
--namespace "AWS/SNS" \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:ops-alerts" \
--metric-name "NumberOfMessagesPublished" \
--statistic "Sum" \
--period 60 \
--evaluation-periods 5 \
--threshold 10 \
--comparison-operator "LessThanThreshold" \
--treat-missing-data "breaching" \
--dimensions "Name=TopicName,Value=order-events"
Note the use of --treat-missing-data "breaching"—when a producer stops entirely, CloudWatch may see no data points, and this setting ensures the alarm fires rather than staying green.
Alarm 3: Subscription-Level Dead Letter Queue Growth
For Lambda subscriptions that push failures to a dead letter queue (DLQ) via an SQS queue, monitor the queue's ApproximateNumberOfMessagesVisible. While this metric lives in the AWS/SQS namespace, it directly reflects SNS delivery health:
aws cloudwatch put-metric-alarm \
--alarm-name "sns-dlq-backlog" \
--alarm-description "DLQ for SNS subscription is growing" \
--namespace "AWS/SQS" \
--metric-name "ApproximateNumberOfMessagesVisible" \
--statistic "Average" \
--period 300 \
--evaluation-periods 3 \
--threshold 50 \
--comparison-operator "GreaterThanThreshold" \
--treat-missing-data "notBreaching" \
--dimensions "Name=QueueName,Value=sns-order-events-dlq"
Alarm 4: Composite Alarm for Multi-Condition Alerting
Composite alarms let you combine multiple metrics into a single alarm without writing complex metric math. For example, alert only if both failure rate is high and publish volume is normal (indicating a real delivery problem rather than a transient zero-volume state):
aws cloudwatch put-composite-alarm \
--alarm-name "sns-critical-delivery-issue" \
--alarm-description "High failure rate AND normal publish volume" \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:pager-alerts" \
--alarm-rule "ALARM(sns-high-delivery-failure-rate) AND OK(sns-low-publish-volume)"
Composite alarms reference existing metric alarms by name. The rule syntax supports ALARM(), OK(), and INSUFFICIENT_DATA() functions combined with AND, OR, and NOT.
Building Dashboards for SNS
CloudWatch Dashboards provide a customizable visual interface. A well-designed SNS dashboard brings together publish rates, delivery success/failure breakdowns, per-subscription health, and alarm status widgets. Dashboards are defined as JSON and can be created via the AWS CLI, CloudFormation, or the console.
Dashboard JSON Structure
A dashboard widget can display metrics, alarms, logs, or text. For SNS, the most useful widgets are metric widgets showing line graphs and stacked area charts. Below is a complete dashboard body JSON you can use:
{
"widgets": [
{
"type": "metric",
"x": 0,
"y": 0,
"width": 12,
"height": 6,
"properties": {
"view": "timeSeries",
"stacked": false,
"metrics": [
[ "AWS/SNS", "NumberOfMessagesPublished", { "stat": "Sum", "period": 60 }, { "label": "Published" } ],
[ ".", "NumberOfNotificationsDelivered", { "stat": "Sum", "period": 60 }, { "label": "Delivered" } ],
[ ".", "NumberOfNotificationsFailed", { "stat": "Sum", "period": 60 }, { "label": "Failed" } ]
],
"region": "us-east-1",
"title": "SNS Topic: order-events — Throughput",
"period": 300,
"stat": "Sum"
}
},
{
"type": "metric",
"x": 12,
"y": 0,
"width": 12,
"height": 6,
"properties": {
"view": "timeSeries",
"stacked": false,
"metrics": [
{
"expression": "(failed / (failed + delivered)) * 100",
"label": "FailureRatePercent",
"id": "e1",
"region": "us-east-1"
},
[ "AWS/SNS", "NumberOfNotificationsFailed", { "stat": "Sum", "period": 300, "id": "failed", "visible": false } ],
[ ".", "NumberOfNotificationsDelivered", { "stat": "Sum", "period": 300, "id": "delivered", "visible": false } ]
],
"region": "us-east-1",
"title": "SNS Topic: order-events — Failure Rate %",
"period": 300
}
},
{
"type": "metric",
"x": 0,
"y": 6,
"width": 8,
"height": 6,
"properties": {
"view": "timeSeries",
"stacked": false,
"metrics": [
[ "AWS/SNS", "NumberOfNotificationsDelivered", "SubscriptionId", "abc123-def456", { "stat": "Sum", "period": 60, "label": "Lambda-sub" } ],
[ ".", "NumberOfNotificationsFailed", "SubscriptionId", "abc123-def456", { "stat": "Sum", "period": 60, "label": "Lambda-sub-failures" } ],
[ ".", "NumberOfNotificationsDelivered", "SubscriptionId", "ghi789-jkl012", { "stat": "Sum", "period": 60, "label": "Email-sub" } ],
[ ".", "NumberOfNotificationsFailed", "SubscriptionId", "ghi789-jkl012", { "stat": "Sum", "period": 60, "label": "Email-sub-failures" } ]
],
"region": "us-east-1",
"title": "Per-Subscription Delivery Breakdown",
"period": 300
}
},
{
"type": "metric",
"x": 8,
"y": 6,
"width": 8,
"height": 6,
"properties": {
"view": "timeSeries",
"stacked": false,
"metrics": [
[ "AWS/SNS", "PublishSize", { "stat": "Average", "period": 300, "label": "AvgPublishSizeBytes" } ],
[ ".", "PublishSize", { "stat": "p90", "period": 300, "label": "P90PublishSizeBytes" } ]
],
"region": "us-east-1",
"title": "SNS Topic: order-events — Publish Size",
"period": 300
}
},
{
"type": "alarm",
"x": 16,
"y": 6,
"width": 8,
"height": 6,
"properties": {
"title": "Active Alarms",
"region": "us-east-1",
"alarms": [
"arn:aws:cloudwatch:us-east-1:123456789012:alarm:sns-high-delivery-failure-rate",
"arn:aws:cloudwatch:us-east-1:123456789012:alarm:sns-low-publish-volume",
"arn:aws:cloudwatch:us-east-1:123456789012:alarm:sns-dlq-backlog"
]
}
}
]
}
Creating the Dashboard via CLI
aws cloudwatch put-dashboard \
--dashboard-name "SNS-Monitoring" \
--dashboard-body file://sns-dashboard.json
After creation, the dashboard appears in the CloudWatch console under Dashboards > SNS-Monitoring. You can update it at any time with a new body, and CloudWatch handles versioning automatically.
Adding Dashboard to CloudFormation / CDK
For infrastructure-as-code teams, embed the dashboard directly in a CloudFormation template:
Resources:
SnsDashboard:
Type: AWS::CloudWatch::Dashboard
Properties:
DashboardName: SNS-Monitoring
DashboardBody: |
{
"widgets": [
{
"type": "metric",
"x": 0, "y": 0, "width": 12, "height": 6,
"properties": {
"view": "timeSeries",
"stacked": false,
"metrics": [
[ "AWS/SNS", "NumberOfMessagesPublished", { "stat": "Sum", "period": 60 } ],
[ ".", "NumberOfNotificationsDelivered", { "stat": "Sum", "period": 60 } ],
[ ".", "NumberOfNotificationsFailed", { "stat": "Sum", "period": 60 } ]
],
"region": "us-east-1",
"title": "SNS Topic Throughput",
"period": 300
}
}
]
}
With the AWS CDK, use the aws-cloudwatch and aws-cloudwatch-actions libraries to programmatically define dashboards, alarms, and metric graphs in TypeScript or Python. The CDK offers high-level constructs like Dashboard, GraphWidget, and AlarmWidget that compile to the same JSON structure.
Best Practices for SNS Monitoring
- Enable detailed monitoring selectively—1-second granularity is valuable for high-throughput production topics but adds cost. Use it on topics that exceed 100 messages per second or serve latency-sensitive workflows.
- Monitor the DLQ, not just the topic—SNS delivers to Lambda, SQS, HTTP, email, and mobile push. Each has its own failure mode. Always pair subscription monitoring with DLQ depth alarms for Lambda and SQS subscriptions.
- Use metric math for rates, not absolute counts—a raw failed count of 50 means nothing without context. Express alarms as percentages:
(failed / (failed + delivered)) * 100. This normalizes across traffic fluctuations. - Set
treat-missing-dataintentionally—for "low volume" alarms, missing data usually means zero traffic and should be treated as breaching. For failure-rate alarms, missing data should benotBreachingto avoid false positives during quiet periods. - Combine alarms with composite rules—a single metric alarm can be noisy. Composite alarms let you express conditions like "high failure rate AND normal publish volume" to reduce alert fatigue.
- Tag topics and subscriptions consistently—use the
TopicNamedimension in alarms rather than topic ARNs where possible. ARNs change if you redeploy infrastructure; names remain stable if you enforce a naming convention. - Dashboard per environment and per topic—create separate dashboards for production and staging. For multi-topic architectures, build a top-level aggregate dashboard plus drill-down topic-specific views.
- Automate alarm creation with CI/CD—bake alarms and dashboards into your deployment pipeline. When a new SNS topic is provisioned via CloudFormation or CDK, its monitoring artifacts should be created simultaneously, not manually afterward.
- Alert on filter policy misconfigurations—monitor
NumberOfNotificationsFilteredOutInvalidAttributes. A spike indicates a publisher changed payload attributes that no longer match subscriber filter policies, silently dropping messages. - Test alarms regularly—use
aws cloudwatch set-alarm-stateto simulate alarm transitions in staging and verify that your notification pathways (SNS → Lambda → Slack/PagerDuty) work end-to-end.
Conclusion
Monitoring SNS with CloudWatch Metrics, Alarms, and Dashboards transforms a black-box pub/sub service into a transparent, accountable component of your architecture. Topic-level metrics give you a macro view of throughput and delivery success; subscription-level metrics let you zoom into individual consumer health; alarms surface anomalies before they cascade; and dashboards tie everything into a single operational view. By applying the patterns in this tutorial—rate-based alarms, composite rules, DLQ monitoring, and infrastructure-as-code dashboard definitions—you build a resilient messaging layer that alerts you proactively rather than leaving failures to be discovered by your users. Start with a single dashboard for your busiest topic, iterate on the alarm thresholds as traffic patterns stabilize, and scale the approach across every SNS topic in your system.