Skip to main content

AWS SNS/SQS

Amazon SNS (Simple Notification Service) and SQS (Simple Queue Service) provide managed messaging for event sourcing on AWS.


Why SNS/SQS

StrengthBenefit
Fully managedNo infrastructure to operate
ServerlessLambda integration
Cost effectivePay per request
High availabilityMulti-AZ by default
Fan-outSNS → multiple SQS queues

Trade-offs

ConcernConsideration
AWS lock-inNot portable to other clouds
256 KB limitLarge events need S3 offloading
OrderingFIFO queues required for ordering

Configuration

[bus]
backend = "sns_sqs"

[bus.sns_sqs]
region = "us-east-1"
topic_prefix = "angzarr"

Environment Variables

export AWS_REGION="us-east-1"
export SNS_SQS_TOPIC_PREFIX="angzarr"
export BUS_BACKEND="sns_sqs"
# AWS credentials via standard mechanisms

Topology

SNS provides fan-out to SQS queues:

SNS Topic: angzarr-events-player

├── SQS: player-projector-queue
├── SQS: output-projector-queue
└── SQS: topology-tracker-queue

SNS Topic: angzarr-events-hand

├── SQS: hand-saga-queue
└── SQS: output-projector-queue

FIFO vs Standard

Standard Queues

  • At-least-once delivery
  • Best-effort ordering
  • Higher throughput

FIFO Queues

  • Exactly-once processing
  • Strict ordering within message groups
  • 300 TPS limit (3000 with batching)

For event sourcing, FIFO queues with message group ID = aggregate root:

sqs.send_message()
.queue_url(&fifo_queue_url)
.message_body(&event_json)
.message_group_id(&format!("{}#{}", domain, root))
.message_deduplication_id(&event_id)
.send()
.await?;

Large Event Handling

Events exceeding 256 KB use S3 for payload storage:

1. Store payload in S3
2. Publish reference to SNS/SQS
3. Consumer fetches from S3

This is the "claim check" pattern, handled automatically by OffloadingEventBus.


Dead Letter Queues

Configure DLQs for failed messages:

# CloudFormation/Terraform
PlayerProjectorDLQ:
Type: AWS::SQS::Queue
Properties:
QueueName: player-projector-dlq

PlayerProjectorQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: player-projector-queue
RedrivePolicy:
deadLetterTargetArn: !GetAtt PlayerProjectorDLQ.Arn
maxReceiveCount: 5

Setup

# Create SNS topics
aws sns create-topic --name angzarr-events-player
aws sns create-topic --name angzarr-events-hand

# Create SQS queues
aws sqs create-queue --queue-name player-projector-queue

# Subscribe queue to topic
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:123456789:angzarr-events-player \
--protocol sqs \
--notification-endpoint arn:aws:sqs:us-east-1:123456789:player-projector-queue

Helm Deployment

# values.yaml
bus:
backend: sns_sqs

sns_sqs:
enabled: true
region: us-east-1
topicPrefix: angzarr
# IAM role-based auth recommended

When to Use SNS/SQS

  • AWS native — Already on AWS
  • Lambda integration — Serverless event handlers
  • Cost sensitive — Pay-per-use model
  • Managed — No operational overhead

Next Steps

  • Pub/Sub — GCP equivalent
  • AMQP — Self-managed alternative