Docs
/
AWS Cloud
Chapter 11

11 — SQS, SNS & EventBridge

Overview

ServiceTypePatternUse Case
SQSQueuePoint-to-pointDecouple services, buffer workloads
SNSTopicPub/Sub (fan-out)Notifications, broadcast to many
EventBridgeEvent BusEvent-driven routingComplex routing, event-driven architecture

SQS (Simple Queue Service)

Producer → [SQS Queue] → Consumer (Lambda / EC2 / ECS)

Messages wait in queue until processed.
Consumer deletes message after successful processing.

Standard vs FIFO

StandardFIFO
ThroughputUnlimited300 msg/sec (3000 with batching)
OrderingBest-effortStrict FIFO
DuplicatesPossible (at-least-once)Exactly-once
Queue namemy-queuemy-queue.fifo
import { SQSClient, SendMessageCommand, ReceiveMessageCommand, DeleteMessageCommand } from '@aws-sdk/client-sqs';

const sqs = new SQSClient({});
const QUEUE_URL = process.env.QUEUE_URL!;

// Send message
await sqs.send(new SendMessageCommand({
  QueueUrl: QUEUE_URL,
  MessageBody: JSON.stringify({ orderId: '123', action: 'process' }),
  DelaySeconds: 0,
}));

// Receive & process (Lambda trigger is easier)
const { Messages } = await sqs.send(new ReceiveMessageCommand({
  QueueUrl: QUEUE_URL,
  MaxNumberOfMessages: 10,
  WaitTimeSeconds: 20,        // Long polling (saves cost)
}));

// Delete after processing
await sqs.send(new DeleteMessageCommand({
  QueueUrl: QUEUE_URL,
  ReceiptHandle: Messages![0].ReceiptHandle!,
}));

Dead Letter Queue (DLQ)

Main Queue → Consumer fails 3 times → DLQ
                                        ↓
                                   Investigate / retry later

SNS (Simple Notification Service)

Publisher → [SNS Topic] → Subscriber 1 (SQS)
                        → Subscriber 2 (Lambda)
                        → Subscriber 3 (Email)
                        → Subscriber 4 (HTTP endpoint)

Fan-Out Pattern (SNS + SQS)

Order placed → SNS Topic → SQS (payment processing)
                          → SQS (inventory update)
                          → SQS (email notification)
                          → Lambda (analytics)

Each subscriber gets a copy of every message.
Each processes independently at its own pace.
import { SNSClient, PublishCommand } from '@aws-sdk/client-sns';

const sns = new SNSClient({});

await sns.send(new PublishCommand({
  TopicArn: 'arn:aws:sns:us-east-1:123456:order-events',
  Message: JSON.stringify({ orderId: '123', status: 'placed' }),
  MessageAttributes: {
    eventType: { DataType: 'String', StringValue: 'ORDER_PLACED' },
  },
}));

EventBridge

Advanced event routing with rules and patterns.

Event Sources → Event Bus → Rules → Targets
                              │
                              ├── Rule: order.placed → Lambda (process)
                              ├── Rule: order.shipped → SQS (notify)
                              └── Rule: schedule(rate 1 hour) → Lambda (cleanup)
import { EventBridgeClient, PutEventsCommand } from '@aws-sdk/client-eventbridge';

const eb = new EventBridgeClient({});

await eb.send(new PutEventsCommand({
  Entries: [{
    Source: 'myapp.orders',
    DetailType: 'OrderPlaced',
    Detail: JSON.stringify({ orderId: '123', total: 49.99 }),
    EventBusName: 'default',
  }],
}));

Event Pattern (Rule)

{
  "source": ["myapp.orders"],
  "detail-type": ["OrderPlaced"],
  "detail": {
    "total": [{ "numeric": [">", 100] }]
  }
}

Scheduled Rules

rate(5 minutes)          → every 5 minutes
rate(1 hour)             → every hour
cron(0 2 * * ? *)       → daily at 2 AM UTC
cron(0 9 ? * MON-FRI *) → weekdays at 9 AM UTC

When to Use What

ScenarioUse
Decouple two servicesSQS
Buffer spiky trafficSQS
Fan-out to multiple consumersSNS + SQS
Complex event routing with rulesEventBridge
Scheduled tasksEventBridge
Cross-account/cross-service eventsEventBridge
Simple notifications (email/SMS)SNS

Key Takeaways

  • SQS = message queue (point-to-point, buffering, decoupling)
  • SNS = pub/sub (fan-out one event to many subscribers)
  • EventBridge = event bus (content-based routing, scheduling, cross-service)
  • Use SNS + SQS fan-out for broadcasting events to multiple independent processors
  • Always configure DLQ for failed message handling
  • Use long polling (WaitTimeSeconds: 20) in SQS to reduce costs
  • EventBridge is the most flexible — prefer it for new event-driven architectures