SNS #
In modern distributed system architecture adopting microservices and event-driven patterns, one of the most frequent needs is distributing a single event to many different receiving services simultaneously. For example, when a user successfully completes a purchase transaction (event: OrderCreated), the system must immediately notify the inventory service to deduct stock, inform the payment service to process the credit card, and trigger the notification service to send a transaction receipt to the user’s email.
If we connect those services synchronously one by one via HTTP calls, our system becomes very rigid, slow, and failure-prone. This is where AWS Simple Notification Service (SNS) takes a vital role. As a fully managed, serverless publish-subscribe (pub/sub) service, SNS lets us broadcast messages to many consumers asynchronously with low latency and global scale.
What is AWS SNS? #
AWS Simple Notification Service (SNS) is a message delivery service based on the Publish-Subscribe (Pub/Sub) model.
In this model, message senders and receivers are structurally separated through an intermediary called a Topic:
- Publisher: The sending component that publishes messages to a specific SNS topic. Publishers don’t need to know who, where, or how many receivers are listening to the topic.
- Topic: The logical communication point where messages are delivered. The topic acts as a distribution channel.
- Subscriber / Consumer: Endpoints that subscribe to the SNS topic. When a new message arrives at the topic, SNS duplicates and pushes the message to all registered subscribers instantly.
flowchart TD
Producer["Order Service (Lambda)"] -->|Publish Event: order-created| Topic["AWS SNS Topic<br/>'order-created'"]
Topic -->|Direct Route| LambdaEmail["Email Service (Lambda)"]
Topic -->|Filter: status = VIP| SQSVIP["SQS VIP Queue (FIFO)"]
SQSVIP --> WorkerVIP["VIP Worker (Fargate)"]
Topic -->|Filter: status = Regular| SQSReg["SQS Regular Queue"]
SQSReg --> WorkerReg["Regular Worker (Fargate)"]
Topic -->|Send to HTTP Endpoint| Webhook["Third-Party Site (Webhook)"]Essential Difference: AWS SNS vs. AWS SQS #
Although both are serverless message services on AWS, SNS and SQS are designed to solve opposite architectural problems.
| Comparison Criteria | AWS SNS (Simple Notification Service) | AWS SQS (Simple Queue Service) |
|---|---|---|
| Communication Model | Publish-Subscribe (Pub/Sub) | Point-to-Point (Queue) |
| Delivery Method | Push Model (SNS directly sends messages to subscribers) | Pull Model (Consumers actively poll for messages) |
| Message Receivers | Many (One-to-Many / Fan-out) | One (One-to-One / Work Queue) |
| Message Durability | Ephemeral (messages discarded immediately after successful delivery) | Durable (messages stored in the queue up to 14 days) |
| Message Ordering | Not guaranteed (FIFO available with throughput limits) | FIFO available with strict ordering option |
| Main Use Cases | Event broadcast, multi-channel notifications, system alerts | Task processing, load leveling, background jobs |
Supported Subscription Types (Receivers) #
AWS SNS is very flexible because it supports delivering messages to various endpoint protocol types:
- Amazon SQS: Delivers SNS messages to an SQS queue. This is the most popular Fan-out architecture pattern for ensuring message durability and reliable async processing.
- AWS Lambda: Instantly triggers a Lambda function to execute serverless logic when a message arrives.
- HTTP / HTTPS: Delivers messages as HTTP POST requests (Webhooks) to external web servers outside the AWS environment.
- Email / Email-JSON: Delivers message content directly to user email inboxes in plain text or structured JSON format.
- SMS (Short Message Service): Delivers text messages directly to mobile phone numbers in over 200 countries for OTP verification or critical alerts.
- Mobile Push Notifications: Delivers notifications directly to iOS, Android, macOS, or Windows mobile apps using Firebase Cloud Messaging (FCM) or Apple Push Notification service (APNs).
Advanced Feature: Message Filtering #
By default, all subscribers registered to an SNS topic receive a copy of every message delivered to that topic. However, we often want specific subscribers to only receive messages relevant to them. The Subscription Filter Policies feature lets us filter messages at the SNS level before they’re delivered to subscribers, saving compute and bandwidth costs on the consumer side.
How Filtering Works #
Publishers include additional metadata called Message Attributes when sending messages to the topic. Subscribers define filtering rules (filter policies) in JSON document format.
Example JSON Filter Policy on a Subscriber: #
Suppose we have a dedicated SQS queue for processing VIP shipment deliveries. We can attach the following filter policy to that SQS subscription on the order-created SNS topic:
{
"store": ["singapore", "jakarta"],
"order_value": [{"numeric": [">=", 1000000]}],
"customer_type": ["VIP"]
}
With the filter policy above, this VIP SQS only receives messages if the message comes from a Singapore or Jakarta store, has a minimum purchase value of IDR 1,000,000, and the customer type is VIP. All other messages not meeting those criteria are automatically discarded by SNS without being sent to that VIP SQS.
Practical Implementation Example: Node.js #
Here’s an example of code using the AWS SDK v3 for Node.js to publish messages to an SNS topic, complete with Message Attributes for filter policy needs.
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";
// Initialize the SNS client
const snsClient = new SNSClient({ region: "ap-southeast-1" });
const TOPIC_ARN = process.env.SNS_TOPIC_ARN;
export const handler = async (event) => {
try {
const orderPayload = {
orderId: "ORD-77621",
items: ["Laptop", "Mouse"],
total: 12500000
};
// Configure the publish command
const command = new PublishCommand({
TopicArn: TOPIC_ARN,
// The main message content must be a String (usually JSON stringified)
Message: JSON.stringify(orderPayload),
Subject: "New Transaction Created",
// ✓ Including Message Attributes for subscriber-level filtering needs
MessageAttributes: {
"customer_type": {
DataType: "String",
StringValue: "VIP"
},
"order_value": {
DataType: "Number",
StringValue: "12500000"
},
"store": {
DataType: "String",
StringValue: "jakarta"
}
}
});
// Send the message to the SNS topic
const response = await snsClient.send(command);
console.log(`Successfully published message to SNS. MessageId: ${response.MessageId}`);
return {
statusCode: 200,
body: JSON.stringify({
success: true,
messageId: response.MessageId
})
};
} catch (error) {
console.error("Failed to publish to SNS", error);
return {
statusCode: 500,
body: JSON.stringify({ error: error.message })
};
}
};
Best Practices for Using SNS #
To ensure reliable asynchronous message delivery using SNS, always apply these design rules:
1. Use the Fan-out Pattern (SNS + SQS) for System Durability #
If we want to trigger async backend processes from SNS messages, don’t connect SNS directly to Lambda functions when performance and data reliability are critical. Why? Because if your Lambda function gets throttled or fails, the push request from SNS is immediately discarded after the retry period expires.
The recommended pattern is SNS -> SQS -> Lambda. The SNS topic broadcasts messages to an SQS queue, and the SQS queue acts as a durable buffer that safely stores messages until the Lambda function is ready to process them.
2. Always Configure a Dead Letter Queue (DLQ) on Subscriptions #
Just like SQS, SNS subscriptions also support Dead Letter Queues (DLQ). If SNS fails to deliver a message to the destination endpoint (e.g., the target HTTP webhook is down) after repeatedly retrying according to the delivery retry policy, SNS moves that message to the designated SQS DLQ. This makes tracking undeliverable data easier.
Summary #
← Previous: SQS Next: Step Functions →
- AWS SNS is a serverless pub/sub messaging service that broadcasts messages from publishers to many subscribers asynchronously.
- Supports the Fan-out architecture (SNS + SQS) that robustly decouples service dependencies without risking message loss when downstream services are down.
- Subscription Filter Policies enable automatic JSON-based message filtering at the SNS level using message attributes, saving consumer compute.
- Supports multi-channel delivery, from internal AWS delivery (SQS, Lambda) to external public delivery (HTTP Webhooks, SMS, Email, Push Notifications).
- Apply DLQ (Dead Letter Queue) at the subscription level to detect, isolate, and analyze messages that failed delivery due to network issues or receiving system failures.