AWS pub/sub messaging service that distributes messages to multiple subscribers simultaneously, enabling fan-out patterns and notifications at scale.
Amazon SNS (Simple Notification Service) is a fully managed pub/sub messaging service that enables sending messages from publishers to multiple subscribers simultaneously. Unlike traditional queue systems, SNS implements the fan-out pattern where a message is distributed to all endpoints subscribed to the topic.
The service operates with topics as logical communication points. Publishers send messages to a topic, and SNS handles delivering copies of the message to all configured subscribers. This architecture completely decouples producers from consumers, enabling independent scalability and system evolution without affecting other components.
SNS supports both standard and FIFO (First-In-First-Out) topics. Standard topics offer virtually unlimited throughput with at-least-once delivery, while FIFO topics guarantee strict ordering and exactly-once delivery with a limit of 300 messages per second per message group (up to 3,000 msg/s per topic).
SNS can deliver messages to multiple endpoint types:
Native AWS services:
External endpoints:
SNS enables granular message filtering using message attributes and filter policies. Each subscriber can define a JSON policy specifying which messages it should receive:
{
"event_type": ["order_created", "order_updated"],
"region": ["us-east-1", "eu-west-1"],
"amount": [{"numeric": [">", 100]}],
"customer_tier": ["premium", "enterprise"]
}This functionality eliminates the need to process and discard irrelevant messages in the consumer, reducing costs and latency. Filters support exact matches, numeric ranges, string prefixes, and allowed value lists.
# Main SNS topic
resource "aws_sns_topic" "order_events" {
name = "order-events"
display_name = "Order Processing Events"
# Delivery configuration
delivery_policy = jsonencode({
"http" = {
"defaultHealthyRetryPolicy" = {
"minDelayTarget" = 20
"maxDelayTarget" = 20
"numRetries" = 3
"numMaxDelayRetries" = 0
"numMinDelayRetries" = 0
"numNoDelayRetries" = 0
"backoffFunction" = "linear"
}
}
})
}
# SQS for inventory processing
resource "aws_sqs_queue" "inventory_processing" {
name = "inventory-processing"
visibility_timeout_seconds = 300
message_retention_seconds = 1209600
# Dead letter queue for failed messages
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.inventory_dlq.arn
maxReceiveCount = 3
})
}
resource "aws_sqs_queue" "inventory_dlq" {
name = "inventory-processing-dlq"
}
# SQS for user notifications
resource "aws_sqs_queue" "user_notifications" {
name = "user-notifications"
visibility_timeout_seconds = 60
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.notifications_dlq.arn
maxReceiveCount = 5
})
}
resource "aws_sqs_queue" "notifications_dlq" {
name = "user-notifications-dlq"
}
# Inventory subscription with filtering
resource "aws_sns_topic_subscription" "inventory_subscription" {
topic_arn = aws_sns_topic.order_events.arn
protocol = "sqs"
endpoint = aws_sqs_queue.inventory_processing.arn
# Only order creation and cancellation events
filter_policy = jsonencode({
event_type = ["order_created", "order_cancelled"]
product_category = ["electronics", "books"]
})
}
# Notifications subscription with different filtering
resource "aws_sns_topic_subscription" "notifications_subscription" {
topic_arn = aws_sns_topic.order_events.arn
protocol = "sqs"
endpoint = aws_sqs_queue.user_notifications.arn
# Only events requiring user notification
filter_policy = jsonencode({
event_type = ["order_created", "order_shipped", "order_delivered"]
notification_required = ["true"]
})
}
# Permissions for SNS to write to SQS
resource "aws_sqs_queue_policy" "inventory_policy" {
queue_url = aws_sqs_queue.inventory_processing.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Service = "sns.amazonaws.com"
}
Action = "sqs:SendMessage"
Resource = aws_sqs_queue.inventory_processing.arn
Condition = {
ArnEquals = {
"aws:SourceArn" = aws_sns_topic.order_events.arn
}
}
}]
})
}
resource "aws_sqs_queue_policy" "notifications_policy" {
queue_url = aws_sqs_queue.user_notifications.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Service = "sns.amazonaws.com"
}
Action = "sqs:SendMessage"
Resource = aws_sqs_queue.user_notifications.arn
Condition = {
ArnEquals = {
"aws:SourceArn" = aws_sns_topic.order_events.arn
}
}
}]
})
}SNS FIFO topics guarantee strict ordering and exactly-once delivery using message group IDs and deduplication IDs:
import boto3
import json
from datetime import datetime
sns = boto3.client('sns')
# Publish FIFO message with grouping
response = sns.publish(
TopicArn='arn:aws:sns:us-east-1:123456789012:order-events.fifo',
Message=json.dumps({
'order_id': 'ord_12345',
'event_type': 'order_created',
'timestamp': datetime.utcnow().isoformat(),
'customer_id': 'cust_67890'
}),
MessageGroupId='customer_67890', # Group by customer
MessageDeduplicationId='ord_12345_created', # Prevent duplicates
MessageAttributes={
'event_type': {
'DataType': 'String',
'StringValue': 'order_created'
},
'customer_tier': {
'DataType': 'String',
'StringValue': 'premium'
}
}
)SNS implements configurable retry policies per endpoint type:
| Endpoint | Total retries | Duration | Configuration |
|---|---|---|---|
| Lambda/SQS | 100,015 | ~23 days | Automatic (exponential backoff) |
| HTTP/HTTPS | 3 (default) | Customizable | Configurable delivery policy |
| Email/SMS/Push | 50 | ~6 hours | Fixed (exponential backoff) |
For HTTP endpoints, you can configure a custom delivery policy that defines retry behavior, including minimum and maximum delays, backoff function, and number of attempts. AWS managed endpoints (Lambda, SQS) have aggressive retries with exponential backoff that can extend for weeks.
SNS enables subscriptions across different AWS accounts, enabling multi-tenant and organizational architectures:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-B:root"
},
"Action": "sns:Subscribe",
"Resource": "arn:aws:sns:us-east-1:ACCOUNT-A:shared-events",
"Condition": {
"StringEquals": {
"sns:Protocol": ["sqs", "lambda"]
}
}
}]
}SNS integrates natively with CloudWatch for observability:
Key metrics:
NumberOfMessagesPublished: Messages published to topicNumberOfNotificationsDelivered: Successful deliveries per endpointNumberOfNotificationsFailed: Delivery failuresPublishSize: Average message sizeSuggested alarms (adjust per use case):
SNS is fundamental in modern event-driven architectures because it solves the coupling problem between services. In distributed systems, direct coupling between components creates fragile dependencies that limit scalability and increase operational complexity.
With SNS, an order service can publish events without knowing which systems consume them. Inventory, billing, notifications, and analytics can subscribe independently. This enables independent service evolution, decoupled deployment, and improved fault tolerance.
The SNS + SQS combination is especially powerful because it combines SNS's immediate distribution with SQS's durability and controlled processing. Teams can process events at their own pace without losing messages, implement backpressure, and handle traffic spikes resiliently.
For system architects, SNS represents the difference between coupled monolithic systems and distributed architectures that scale. It's the infrastructure that enables patterns like Event Sourcing, CQRS, and truly decoupled microservices.
Cloud computing model where the provider manages infrastructure automatically, allowing code execution without provisioning or managing servers, paying only for actual usage.
AWS fully managed message queue service that decouples distributed application components, guaranteeing message delivery with unlimited scalability.
Architectural pattern where components communicate through asynchronous events, enabling decoupled, scalable, and reactive systems.
AWS serverless compute service that runs code in response to events without provisioning or managing servers, automatically scaling from zero to thousands of concurrent executions.
Ability to understand a system's internal state from its external outputs: logs, metrics, and traces, enabling problem diagnosis without direct system access.
Architecture design for scaling a personal second brain to a production system with AWS serverless — from the current prototype to specialized use cases in legal, research, and community building.
Collection of 13 Terraform modules published on the Terraform Registry for deploying serverless architectures on AWS, with 12 examples covering basic ECS to full-stack CRUD with DynamoDB and AgentCore with MCP.
Production-ready serverless backend for a personal knowledge graph — DynamoDB, Lambda, Bedrock, MCP, Step Functions. The implementation of the architecture described in the 'From Prototype to Production' essay.