devuplabs.cloud
Free previewConcept guide9 min read

Overview

Read this before the SNS hands-on lab, or any time you need to broadcast an event to multiple systems and want to understand the right tool and model.

The Problem SNS Solves

You've just processed a payment. Now three things need to happen:

  1. 1Send a confirmation email to the customer
  2. 2Update the invoice status in the audit service
  3. 3Trigger a fraud detection check

The naive approach, call each service directly from your payment service:

javascript
Payment ServiceHTTP call → Email ServiceHTTP call → Audit ServiceHTTP call → Fraud Detection

This works until it doesn't. Adding a fourth subscriber means changing the Payment Service. If Email Service is slow, payment processing slows. If Audit Service is down, the whole payment fails. Every subscriber is a dependency of the producer. SNS breaks this coupling:

javascript
Payment ServiceSNS Topic → ├── Email Service
                               ├── Audit Service
                               └── Fraud Detection

Payment Service publishes one message to the topic and returns. SNS delivers it to all subscribers simultaneously. Adding a fourth subscriber requires no change to the Payment Service, you just add a subscription. If Email Service is slow, it doesn't affect the others. This is fan-out: one event, many independent reactions.


What SNS Is

Amazon Simple Notification Service (SNS) is a fully managed pub/sub messaging service. A producer publishes a message to a topic. SNS immediately pushes that message to all subscribers of that topic. Key properties:

  • Push-based: SNS delivers to subscribers. Subscribers don't poll.
  • Fan-out: one publish, many deliveries simultaneously
  • No persistence: SNS delivers immediately and moves on. If a subscriber is unavailable, the message is retried with backoff, but SNS is not a queue. It doesn't store messages for later consumption.
  • Fully managed: no servers, no capacity planning
  • Multiple protocol support: subscribers can be SQS queues, Lambda functions, HTTP/HTTPS endpoints, email addresses, SMS, or mobile push notifications

Core Concepts

Topic

A topic is the channel through which messages flow. Producers publish to a topic. Subscribers receive from a topic. A topic has an ARN: arn:aws:sns:ap-south-1:123456789:my-topic. Topics are either Standard (high throughput, best-effort ordering) or FIFO (strict ordering, exactly-once delivery, lower throughput, mirrors SQS FIFO).

Publisher

Any AWS service or application that calls Publish on the topic. One publisher, or many. Publishers don't know who the subscribers are.

Subscriber

An endpoint registered to receive messages from a topic. Supported subscriber types:

ProtocolWhat receives the messageUse for
SQSAn SQS queueFan-out with persistence and independent processing
LambdaA Lambda function invoked directlyServerless event processing
HTTP/HTTPSAn HTTP endpoint (your API)Webhooks to external services
EmailAn email addressHuman notifications, alerts
SMSA phone numberText message alerts
Mobile PushiOS/Android push notificationMobile app notifications
FirehoseKinesis Data Firehose delivery streamStreaming to S3, Redshift, OpenSearch

Message

A message is a string up to 256KB. SNS wraps it in an envelope when delivering:

json
{
  "Type": "Notification",
  "MessageId": "abc-123",
  "TopicArn": "arn:aws:sns:...",
  "Message": "your actual payload here",
  "Timestamp": "2024-01-25T10:00:00Z",
  "Subject": "optional subject",
  "MessageAttributes": {}
}

The Message field is what you published. The envelope is added by SNS. Your subscriber receives the full envelope, you must parse it to get the original payload. This is a common source of confusion: SQS consumers reading from an SNS-subscribed queue receive the SNS envelope, not just the raw message.


The Delivery Model

Push, not pull

SNS pushes messages to subscribers. The moment you call Publish, SNS attempts delivery to every subscriber concurrently. Subscribers don't check in periodically. SNS comes to them.

Retry policy

For HTTP/HTTPS subscribers, SNS retries failed deliveries with exponential backoff. By default: 3 immediate retries, then 20 retries with delay up to 20 minutes, totalling 23 delivery attempts before giving up. For SQS and Lambda subscribers, the retry semantics are handled by those services (SQS visibility timeout, Lambda retry policy).

No persistence

SNS does not store messages. If all retries to a subscriber fail, the message is lost from SNS's perspective. This is why SNS → SQS is the standard pattern for anything that needs durability: SQS holds the message until the consumer confirms processing.

SNS vs SQS delivery guarantee

SQS guarantees every message is processed (it keeps the message until a consumer deletes it. SNS guarantees every message is *attempted*) it tries to deliver but doesn't keep the message. For critical workloads, always land SNS messages into an SQS queue, not directly into HTTP endpoints or Lambda, so you get both fan-out and durability.


Message Filtering

By default, every subscriber receives every message published to the topic. Message filtering lets subscribers declare which messages they care about, using filter policies on message attributes. Example: a payment topic publishes both successful and failed payments. The fraud detection service only cares about failures. The email service cares about both but sends different emails.

json
// Payment Service publishes with attributes:
{
  "Message": "{\"paymentId\": \"PAY-001\", ...}",
  "MessageAttributes": {
    "status": {"DataType": "String", "StringValue": "FAILED"},
    "amount": {"DataType": "Number", "StringValue": "149.99"}
  }
}

// Fraud Detection subscription filter policy:
// Only receive messages where status = FAILED
{"status": ["FAILED"]}

// High-value transactions filter:
// Only receive messages where amount > 100
{"amount": [{"numeric": [">", 100]}]}

SNS evaluates the filter policy before delivery. Messages that don't match are never delivered to that subscriber, they're not billed for it either. This keeps each subscriber's queue or Lambda clean, processing only the messages it cares about.

Filter policy scope: by default, filtering is on message attributes. You can also enable filtering on the message body (JSON), but this requires FilterPolicyScope: MessageBody.


SNS + SQS: Fan-out with Persistence

This is the most important SNS pattern. Used everywhere.

javascript
Event ProducerSNS Topic
     ├──── SQS Queue A → Lambda / Worker (PDF generation)
     ├──── SQS Queue B → Lambda / Worker (Email sending)
     └──── SQS Queue C → Lambda / Worker (Audit logging)

Why SQS between SNS and the consumer, instead of SNS → Lambda directly?

  • Durability: SQS holds the message if the Lambda is throttled, unavailable, or slow. SNS → Lambda directly means a Lambda throttle = message lost after retries.
  • Rate control: SQS lets you control how fast Lambda processes (batch size, concurrency). SNS → Lambda directly invokes Lambda for every message immediately, a spike of 10,000 messages means 10,000 Lambda invocations at once.
  • DLQ: SQS DLQ captures messages that repeatedly fail. SNS → Lambda has no equivalent capture mechanism.
  • Independent scaling: each SQS queue drains at its own pace. PDF generation might take 5 seconds per message; email sending might take 50ms. They don't block each other.

The only reason to use SNS → Lambda directly (without SQS) is when you need the lowest possible latency and can tolerate message loss under Lambda throttling.


SNS Standard vs. FIFO

Standard Topic

  • Best-effort ordering
  • At-least-once delivery
  • Unlimited throughput
  • Subscribers: SQS Standard, Lambda, HTTP, email, SMS, mobile push, Firehose

FIFO Topic

  • Strict ordering (within message group)
  • Exactly-once delivery
  • Up to 300 messages/sec (3,000 with batching)
  • Subscribers: SQS FIFO only. No HTTP, email, Lambda directly.
  • Use when the order of events is semantically meaningful, account created must be processed before account updated

Message Attributes vs. Message Body

Message attributes are metadata attached to a message, key-value pairs with a data type. They're used for:

  • Filter policies (SNS reads attributes without parsing the body)
  • Routing decisions
  • Passing metadata without changing the payload schema

Message body is the actual content. SNS delivers it as a string. Structure it however you want (JSON is standard). Attributes are more efficient for filtering because SNS can evaluate them without deserialising the body.


SNS as an Alert System

SNS is the delivery mechanism for CloudWatch Alarms. When an alarm transitions to ALARM state, it publishes to an SNS topic. The topic delivers to email, SMS, Lambda, PagerDuty (via HTTPS), Slack (via Lambda), or any combination. This is the standard AWS alerting pattern:

javascript
CloudWatch AlarmSNS Topic → ├─ Email (team)
                               ├─ SMS (on-call)
                               └─ LambdaPagerDuty / Slack

You've seen this in the CloudWatch Alarms lab. The SNS topic is the fan-out layer that lets one alarm notify multiple channels simultaneously.


SNS vs. SQS vs. EventBridge

DimensionSNSSQSEventBridge
ModelPub/sub (push)Queue (pull)Event bus (push, rules-based)
Consumers per messageMany (all subscribers)OneMany (matching rules)
Message persistenceNo (retry only)Yes (up to 14 days)No (24h retry)
FilteringMessage attribute or body filter policiesNone (all consumers see all messages)Rich content-based rules (JSON pattern matching)
AWS service sourcesAny publisher calls Publish APIAny producer calls SendMessage APINative events from 200+ AWS services
Cross-account deliveryYes (resource policy)Yes (resource policy)Yes (event bus to bus)

Use SNS when: one event needs to go to multiple systems simultaneously, and you want simplicity. The fan-out pattern.

Use SQS when: one unit of work needs to be processed exactly once by one worker. The work queue pattern.

Use EventBridge when: you need content-based routing with complex rules, or you're reacting to events from AWS services (S3 object created, EC2 state change, etc.).


Subscription Confirmation

For HTTP/HTTPS and email subscribers, SNS requires subscription confirmation before delivering messages. When you create the subscription, SNS sends a confirmation request to the endpoint. The endpoint must respond by visiting a confirmation URL (email) or replying with the token (HTTP). This prevents SNS from being used to spam arbitrary endpoints. If you've set up billing alerts and wondered why emails didn't arrive, it's almost always an unconfirmed subscription. SQS and Lambda subscriptions don't require confirmation. IAM policy is sufficient.


Cost Model

  • Free tier: 1 million publishes/month, 1,000 email deliveries/month, always free
  • Publishes: $0.50 per million after free tier
  • HTTP/HTTPS deliveries: $0.60 per million
  • SQS deliveries: free (SQS charges apply separately)
  • Lambda deliveries: free (Lambda charges apply separately)
  • Email/SMS: email is cheap ($2/100k), SMS varies by country and carrier
  • Data transfer: free within the same region

SNS is extremely cheap for the fan-out it provides. The cost is almost always dominated by the downstream services (SQS, Lambda) rather than SNS itself.


Summary

SNS is a megaphone. You speak once into it, and everyone who's listening hears you simultaneously.

It doesn't remember what you said, if someone wasn't listening, they missed it. For guaranteed delivery to each listener, put an SQS queue between SNS and each consumer. That's the SNS + SQS fan-out pattern, and it's the backbone of most event-driven architectures on AWS.

Unlock all 24 AWS services & 291+ lab sessions (~180 hours)

Pricing