AWS Builder Center

I Learned SQS Can Hold a Job. But How Do I Send the Same Event to Multiple Services?

After learning about Amazon SQS, I understood how queues help applications process work asynchronously. But I had another question: what happens when multiple services need to react to the same event? That's where Amazon SNS and the fan-out pattern started making sense to me. In this article, I explain how SNS, SQS, message filtering, and event-driven architecture work together to build more flexible serverless applications.

In my previous article, I wrote about Amazon SQS and how queues can help serverless applications handle traffic spikes, retries, and background processing.

That changed how I thought about application architecture.
Instead of processing everything immediately, an application can place work into a queue and let another component handle it.
But then I started thinking about a different problem.
Imagine a customer places an order.
That single event might require several things to happen:
  • Update inventory.
  • Generate an invoice.
  • Send a confirmation email.
  • Update analytics.
  • Notify another internal service.
My first instinct would be to make one Lambda function call all these services.
Something like this:
1
2
3
4
5
6
7
8
9
10
11
12
Order Created
|
v
Lambda
|
+------------+------------+
| | |
v v v
Inventory Invoice Email
|
v
Analytics
This could work, but now the original function needs to know about several downstream systems.
What happens when I add another service?
What happens when one service becomes temporarily unavailable?
What happens when different teams want to process the same event independently?
That's when I started understanding a different pattern:
Instead of making one service call everyone else, publish an event and let multiple services react to it.
This is where Amazon SNS comes in.

What Is Amazon SNS?

Amazon SNS stands for Amazon Simple Notification Service.
It is a managed publish-subscribe messaging service that allows publishers to send messages to topics, which deliver those messages to their subscribers.
The simplest way I understand it is:
Publish once. Let multiple subscribers receive the message.
For example:
1
2
3
4
5
6
7
8
9
Publisher
|
v
SNS Topic
|
+----------+----------+
| | |
v v v
Service A Service B Service C
The publisher doesn't need to call every service individually.
It publishes a message to the topic, and SNS handles delivery to the configured subscribers.
That simple idea is the foundation of the fan-out pattern.

What Is the Fan-Out Pattern?

Fan-out is a messaging pattern in which one message is distributed to multiple consumers or destinations.
Imagine a new order is placed.
The application publishes an event:
1
2
3
4
5
6
{
"eventType": "OrderCreated",
"orderId": "ORD-123",
"customerId": "USER-456",
"total": 2499
}
Instead of sending that message separately to each downstream service, the publisher sends it to an SNS topic.
1
2
3
4
5
6
7
8
9
OrderCreated
|
v
SNS Topic
|
+---+---+---+
| | | |
v v v v
Inventory Invoice Email Analytics
Each subscriber can receive its own delivery of the published message.
The inventory service can update stock.
The invoice service can generate an invoice.
The notification service can send an email.
The analytics service can record the order.
All of them can react independently to the same event.
This is the part that finally made SNS click for me.

Why Not Just Call Every Lambda Function Directly?

That was my first question.
Why introduce SNS when one Lambda function can invoke several other Lambda functions?
The problem isn't that direct invocation is always wrong.
The problem is that the producer becomes responsible for coordinating more downstream dependencies.
Consider this architecture:
1
2
3
4
5
6
7
8
9
Order Lambda
|
+----> Inventory Lambda
|
+----> Invoice Lambda
|
+----> Email Lambda
|
+----> Analytics Lambda
Now imagine adding a fraud detection service.
The original function needs to know about that integration too.
Over time, this can make the code more difficult to change and maintain.
With SNS, the architecture can become:
1
2
3
4
5
6
7
8
9
Order Lambda
|
v
SNS Topic
|
+---+---+---+
| | | |
v v v v
Stock Invoice Email Analytics
The producer focuses on publishing the event.
The subscribers focus on their own responsibilities.
That separation can make the application easier to extend.

SNS vs. SQS: The Difference That Matters

After learning about SQS, I initially found SNS confusing because both services involve messages.
But they solve different problems.

Amazon SQS

SQS is a message queue.
It holds messages until consumers retrieve and process them, or until they expire according to the queue's retention settings.
A useful mental model is:
1
2
3
4
5
6
7
Producer
|
v
SQS Queue
|
v
Consumer
When multiple consumers read from the same queue, they generally compete to process messages from that queue rather than each receiving a separate copy.
SQS is useful when I want to buffer work and control how it is processed.

Amazon SNS

SNS is a publish-subscribe messaging service.
A publisher sends a message to a topic, and SNS delivers it to the topic's subscribers.
1
2
3
4
5
6
7
8
9
10
Publisher
|
v
SNS Topic
|
+------> Subscriber A
|
+------> Subscriber B
|
+------> Subscriber C
Each subscriber can receive the same published message.
SNS is useful when multiple independent systems need to know that something happened.

My Mental Model

1
2
3
4
5
6
7
8
SQS
→ Hold work until a consumer processes it.

SNS
→ Distribute a message to multiple subscribers.

EventBridge
→ Match events against rules and route them to targets.
These services overlap in some capabilities, but they aren't interchangeable in every situation.
The right choice depends on what the application needs to do.

Why SNS and SQS Are Even More Interesting Together

This is where the architecture became much more interesting to me.
SNS can broadcast a message to multiple subscribers.
But what happens if one subscriber is temporarily unavailable or needs to process work more slowly?
Direct delivery to that subscriber may not provide the same buffering behavior as a queue.
So AWS supports a useful pattern:
SNS topic → separate SQS queue for each consumer.
For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
OrderCreated
|
v
SNS Topic
|
+------------+------------+
| | |
v v v
SQS Queue A SQS Queue B SQS Queue C
| | |
v v v
Inventory Invoice Email
Worker Worker Worker
Now each consumer has its own queue.
The inventory service processes messages from Queue A.
The invoice service processes messages from Queue B.
The email service processes messages from Queue C.
Each service can process its backlog independently.
If the email service becomes unavailable, its queue can hold messages while the other services continue their work, subject to their own health and permissions.
This pattern is commonly called SNS-to-SQS fan-out or topic-queue chaining.
It combines two useful properties:
  • SNS distributes the event to multiple consumers.
  • SQS buffers work separately for each consumer.
That is a much more flexible architecture than making one Lambda function coordinate everything.

A Real-World Example: An Online Store

Imagine I am building an online store.
When an order is placed, the application publishes an OrderCreated message.
The architecture could look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Customer Places Order
|
v
Order Service
|
v
SNS Topic
|
+-----+------+------+
| | |
v v v
SQS Inventory SQS SQS
Queue Invoice Email
| | |
v v v
Stock Update Invoice Confirmation
Let's look at the responsibilities.
Inventory service
Processes the order event and updates stock availability.
Invoice service
Processes the order details and generates an invoice.
Notification service
Sends a confirmation to the customer.
Each service can evolve independently.
For example, I could replace the invoice implementation without redesigning the entire order service, provided the event contract remains compatible.
That's the kind of flexibility I want when designing distributed systems.

Message Filtering: Not Every Subscriber Needs Every Message

Another useful SNS feature is subscription filtering.
Imagine my application publishes different events:
1
2
3
4
OrderCreated
OrderCancelled
PaymentCompleted
PaymentFailed
Not every subscriber needs all four events.
The inventory service might only need order-related messages.
The payment analytics service might only need payment-related messages.
Without filtering, consumers may receive messages they don't care about and then discard them in their own code.
SNS subscription filter policies can restrict which messages are delivered to each subscriber.
For example, suppose I publish this message:
1
2
3
4
5
{
"eventType": "OrderCreated",
"orderType": "digital",
"orderId": "ORD-123"
}
A subscription could use a filter policy like this:
1
2
3
{
"orderType": ["digital"]
}
For that policy to match the field shown above, the subscription must be configured to evaluate the message body.
SNS also supports filtering using message attributes.
Conceptually:
1
2
3
4
5
6
7
8
9
SNS Topic
|
+------+------+
| |
v v
Digital Orders Physical Orders
| |
v v
Digital Worker Shipping Worker
Each subscriber can receive only the messages that match its filter policy.
This moves part of the routing logic out of the publisher and into the messaging configuration.
One important detail: changes to subscription filter policies can take time to propagate because AWS uses an eventually consistent distributed system. They should not be treated as instantaneous security controls.

SNS vs. EventBridge

Since I recently wrote about Amazon EventBridge, I wanted to understand where it fits into this picture.
Both SNS and EventBridge can help distribute events, but their strengths differ.
FeatureAmazon SNSAmazon EventBridge
Core ideaPublish-subscribe messagingEvent routing using rules
Main use caseFan-out to subscribersReacting to and routing events
FilteringSubscription filter policiesEvent pattern matching
IntegrationsSQS, Lambda, HTTP/S, email, SMS and othersAWS services, SaaS integrations and API destinations
Useful mental modelBroadcast a messageMatch an event and route it
For example, if I want to notify several independent services about an order, SNS is a natural option.
If I want to route events based on detailed event patterns, integrate with supported SaaS providers, or build a broader event-driven architecture, EventBridge may be a better fit.
There is no universal winner.
I need to understand the communication pattern before selecting the service.

What Happens When Delivery Fails?

This is where I started thinking beyond the happy path.
Imagine SNS publishes an event, but one subscriber cannot receive it.
What happens?
The answer depends on the subscription endpoint and its delivery behavior.
SNS has delivery retry policies for supported endpoints. It also supports dead-letter queues for subscriptions where delivery continues to fail.
For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SNS Topic
|
v
Subscriber Delivery
|
v
Temporary Failure
|
v
Retry Delivery
|
v
Retries Exhausted
|
v
Subscription DLQ
A dead-letter queue can help retain failed deliveries for later inspection and diagnosis.
But I shouldn't assume that every message is guaranteed to reach every subscriber regardless of configuration.
I still need to configure permissions, understand the delivery policy for the endpoint, monitor failures, and decide how undeliverable messages should be handled.
For subscribers that need a durable backlog and independent processing, an SQS queue is often a useful layer in the design.

What If the Consumer Processes a Message Twice?

This connects directly to my SQS article.
Distributed messaging systems can involve retries and duplicate processing.
Even if a service receives the same logical event more than once, I don't want it to create duplicate invoices or perform the same business action repeatedly.
For example:
1
2
3
4
5
6
7
8
9
10
OrderCreated
|
v
Invoice Worker
|
v
Invoice Generated
|
v
Same Event Delivered Again
If the worker blindly generates another invoice, the system may behave incorrectly.
This is where idempotency matters.
A consumer can use an event identifier or another reliable business key to track whether the operation has already been completed.
Conceptually:
1
2
3
4
5
6
7
8
9
10
11
12
Receive Event
|
v
Already Processed?
/ \
Yes No
| |
v v
Skip Process
|
v
Save Result
The exact implementation depends on the application, but the principle is important:
Reliable messaging requires consumers to handle retries and duplicates deliberately.

How I Would Use SNS in an AI Application

This is where SNS connects with the AI concepts I've been learning.
Imagine I build an AI document processing application.
When a document is uploaded, the application can publish an event.
Different services can then react independently.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Document Uploaded
|
v
SNS Topic
|
+------------+------------+
| | |
v v v
SQS Queue SQS Queue SQS Queue
| | |
v v v
Text Extraction AI Summary Notification
| |
v v
Processed Amazon Bedrock
Data
The text extraction worker could prepare a document for the knowledge base.
The AI worker could generate a summary.
The notification worker could tell the user when processing finishes.
The producers and consumers don't need to be directly connected to every other component.
This also leaves room to add more subscribers later without redesigning the entire application.
Of course, this doesn't mean every AI application needs SNS.
For a simple synchronous API, direct calls may be sufficient. SNS becomes more interesting when the same event should trigger multiple independent reactions.

What I Would Actually Build

I want to test this pattern with a small serverless project instead of just memorizing definitions.
The project could be an order notification system.
First, I would create an SNS topic called OrderCreated.
Then I would create separate SQS queues for different consumers.
1
2
3
4
5
6
7
8
9
10
SNS Topic
OrderCreated
|
+-----------+-----------+
| |
v v
Inventory Queue Email Queue
| |
v v
Inventory Lambda Email Lambda
Next, I would configure the subscriptions and the permissions required for SNS to deliver messages to those queues.
Then I would publish a sample order event and verify that both queues receive the appropriate message.
Finally, I would test a few failure cases:
  • What happens when one consumer is unavailable?
  • Can each queue build its own backlog?
  • What happens when a message is processed twice?
  • Can filtering prevent irrelevant messages from reaching a subscriber?
  • How can I monitor failed deliveries and queue backlogs?
That would give me practical experience with SNS, SQS, Lambda, IAM permissions, and asynchronous messaging.

My Current Mental Model

After learning about SQS, SNS, and EventBridge, I now think about these services as different tools for connecting application components.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Amazon SQS
|
v
Buffer work and process it asynchronously.

Amazon SNS
|
v
Publish a message to multiple subscribers.

Amazon EventBridge
|
v
Match events against rules and route them to targets.
And they can work together:
1
2
3
4
5
6
7
8
9
10
11
12
Producer
|
v
SNS Topic
|
+-------+-------+
| |
v v
SQS Queue SQS Queue
| |
v v
Worker A Worker B
Each service has a specific responsibility.
The goal isn't to use every AWS service in every application.
The goal is to choose the simplest architecture that meets the application's requirements.

What I Understand Now

Before learning about SNS, I thought about a new event as something a service had to handle itself.
Now I understand that one event can be useful to several independent services.
SNS gives me a publish-subscribe mechanism for distributing that message.
SQS gives consumers a place to buffer work and process it independently.
EventBridge provides another way to route events based on matching rules.
These aren't just three different AWS products with similar names.
They represent different ways to design communication between components.
The biggest lesson for me is this: one event doesn't have to mean one action.
Sometimes a single event can trigger several independent workflows, each with its own responsibilities, processing rate, and failure handling.
And understanding that pattern is another step toward designing cloud applications that are easier to extend and maintain.
I'm still learning these concepts, but I want to keep moving beyond isolated service tutorials and start building systems where the pieces actually work together.

Further Reading

Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article