Messaging and Integration

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

See the section bibliography for the reference material consulted while preparing these pages.

This page covers the AWS services that let one part of an application hand work or facts to another without waiting for it: queues (Amazon SQS), publish/subscribe topics (Amazon SNS), event routers (Amazon EventBridge), workflow orchestration (AWS Step Functions) and, more briefly, the managed brokers and streams (Amazon MQ, Amazon MSK, Amazon Kinesis). Commands are current for AWS CLI v2 (2.37 line), the AWS SDK for Java 2.x and Spring Cloud AWS 4.x (Spring Boot 4) or 3.4.x (Spring Boot 3.5); quotas, versions and console names were checked against the official documentation on 2026-10-01 and should be re-verified with aws --version and the linked pages before you rely on exact numbers. Examples use the placeholder Region us-east-1 and the placeholder account ID 111122223333.

In the running Bookshelf scenario, orders-api accepts an order and must tell several other parties: the notifier worker that sends the confirmation email (see SES email), an archive and analytics consumer, and eventually a fulfilment workflow. Calling each of them synchronously would make order placement as slow and as fragile as the slowest dependency. Instead orders-api publishes one event and every interested party consumes it at its own pace. The notifier is fed from the SQS queue notifier-queue (with its dead-letter queue notifier-dlq) that the Lambda page already wires to a function; this page shows where that queue comes from and how events reach it. For the Lambda side see Lambda: event-driven and serverless apps.

The protocol and pattern theory behind these services is not repeated here; it lives in messaging models and patterns, delivery guarantees and messaging protocols. For the Azure counterparts (Service Bus, Event Grid, Event Hubs) see the Azure section starting at Azure.

Choosing between the services

The first decision is what you are sending. A command tells one consumer to do something and expects it to be done eventually; an event states that something happened and may interest zero, one or many consumers; a stream is an ordered, replayable log that many consumers read at their own offsets.

Service Model Typical use Delivery and ordering

SQS

Pull-based queue; each message is processed by one consumer of the queue

Work queues, buffering, decoupling a producer from a slow consumer, the notifier

Standard: at least once, best-effort ordering. FIFO: exactly-once processing within the deduplication window, strict order per message group

SNS

Push-based topic; each message goes to every subscriber (optionally filtered)

Fan-out of one event to queues, Lambda functions, HTTP endpoints, email and SMS

Standard: at least once, best-effort ordering. FIFO topics: ordering and deduplication, FIFO queue subscribers only

EventBridge event bus

Content-based router with rules (Classic) or subscribers (Custom Event Bus)

Routing AWS service events and your own application events to many targets, cross-account

At least once; the Custom Event Bus adds retention, ordered (FIFO) delivery per event group and replay

EventBridge Pipes

Point-to-point pipeline: source, filter, enrichment, target

Connecting a queue or stream to a target without glue code

Follows the source’s semantics

Step Functions

State machine orchestrating many steps

Multi-step flows with retries, branching, waiting and compensation

Standard: exactly-once state execution; Express: at-least-once (asynchronous) or at-most-once (synchronous)

Kinesis Data Streams

Partitioned, replayable log; many consumers

High-volume ordered ingestion (clickstreams, telemetry), real-time analytics

Ordered per shard, retention 24 hours to 365 days

MSK

Apache Kafka, managed

Existing Kafka applications and ecosystem

Kafka semantics, ordered per partition

Amazon MQ

Managed ActiveMQ or RabbitMQ brokers

Lift-and-shift of JMS, AMQP or MQTT applications

Broker semantics

A rule of thumb for new work on AWS: start with SQS when one consumer group must process each message, add SNS or EventBridge in front when several consumers need the same message, use Step Functions when the order of steps matters, and reach for Kinesis or MSK when you need a replayable log. Choose Amazon MQ only to migrate an application that already speaks JMS or AMQP; its brokers are provisioned and billed by the hour, unlike the serverless services above.

The Bookshelf order flow combines them: orders-api publishes OrderPlaced to an SNS topic, the topic fans out to two SQS queues, and each queue has its own consumer and its own dead-letter queue.

flowchart LR API["orders-api
publishes OrderPlaced"] --> T(("SNS topic
bookshelf-order-events")) T -->|"eventType = OrderPlaced"| Q1["SQS notifier-queue"] T -->|"all events"| Q2["SQS order-archive-queue"] Q1 --> N["notifier
Lambda or container"] N --> SES["Amazon SES
confirmation email"] Q2 --> A["archive consumer"] Q1 -. "after 5 failed receives" .-> D1["notifier-dlq"] Q2 -. "after 5 failed receives" .-> D2["order-archive-dlq"]

Amazon SQS

Amazon Simple Queue Service is a fully managed message queue. Producers send messages; consumers poll, process and then delete them. The queue stores each message redundantly across Availability Zones until it is deleted or its retention period expires, so a consumer outage never loses work.

Standard and FIFO queues

Aspect Standard queue FIFO queue

Throughput

Nearly unlimited API calls per second

300 transactions per second per API action per partition, or 3,000 messages per second with batching; high-throughput mode raises this to tens of thousands of transactions per second in the busiest Regions (limits vary by Region)

Ordering

Best effort; messages can arrive out of order

Strict order within a message group (MessageGroupId is required)

Duplicates

At-least-once delivery; occasional duplicates

Deduplicated for 5 minutes by MessageDeduplicationId or by content hash when content-based deduplication is on

Name

Any

Must end in .fifo

Scaling consumers

Any number of concurrent consumers

Concurrency is limited by the number of active message groups

Use it for

Work distribution where order does not matter and handlers are idempotent

Per-entity ordering (all events of one order, one account) and no duplicates

Fair queues are a standard-queue feature: when you set a MessageGroupId on messages sent to a standard queue, SQS mitigates the noisy-neighbour problem by keeping the dwell time of quiet groups low while a busy group has a backlog. Use them for multi-tenant queues where one tenant could otherwise starve the others.

Limits worth knowing (checked 2026-10-01): a message is at most 1 MiB (1,048,576 bytes); larger payloads go to S3 and the message carries a pointer, which the SQS Extended Client Library for Java automates up to 2 GB. Retention defaults to 4 days and can be 1 minute to 14 days. A message can carry up to 10 attributes, and a batch call handles at most 10 messages. Older guides and tutorials still quote a 256 KiB message limit, which was raised to 1 MiB in 2025.

Visibility timeout, long polling and delay

When a consumer receives a message, SQS does not remove it; it hides it for the visibility timeout (default 30 seconds, minimum 0, maximum 12 hours). If the consumer deletes the message within that time, it is gone. If the consumer crashes or is too slow, the message becomes visible again and another consumer receives it. This is what makes delivery at least once, and why consumers must be idempotent. Set the visibility timeout comfortably above the longest processing time (for a Lambda consumer, at least the function timeout; the Lambda page recommends about six times), or extend it for long jobs with change-message-visibility.

Short polling returns immediately, often empty, and every empty response is a billed request. Long polling waits up to 20 seconds for a message (ReceiveMessageWaitTimeSeconds, or --wait-time-seconds per call) and is the setting to use almost everywhere: fewer empty receives, lower cost, lower latency. Delay queues (DelaySeconds, up to 15 minutes) hide new messages for a while, and per-message timers do the same for individual messages on standard queues.

Dead-letter queues and redrive

A dead-letter queue (DLQ) is an ordinary SQS queue of the same type (standard or FIFO) that receives messages the source queue could not get processed. The source queue’s redrive policy names the DLQ and maxReceiveCount, the number of receives after which a message is moved. Practical rules:

  • Set the DLQ retention period longer than the source queue’s, because the original enqueue time is preserved and the clock keeps running; a message can otherwise expire in the DLQ before anyone looks at it.

  • Choose maxReceiveCount of about 5 or more so transient errors and throttling do not dead-letter healthy messages.

  • Alarm on the DLQ metric ApproximateNumberOfMessagesVisible greater than zero.

  • After fixing the bug, redrive the messages back to the source queue (the console’s Start DLQ redrive action, or start-message-move-task) instead of writing a one-off script.

In the AWS Management Console

  1. Select the Region in the top bar (the examples assume us-east-1), open Amazon SQS, then Queues, Create queue.

  2. Under Type choose Standard (or FIFO, which fixes the name suffix .fifo), and name the dead-letter queue notifier-dlq. Keep the defaults, set Message retention period to 14 days, and choose Create queue.

  3. Create the source queue notifier-queue: set Visibility timeout to 3 minutes, Receive message wait time to 20 seconds, and under Dead-letter queue choose Enabled, select notifier-dlq and set Maximum receives to 5.

  4. Leave Encryption on its default (SQS-managed encryption is on by default; choose AWS KMS key when you need to audit or restrict key use; see Secrets Manager, Parameter Store and KMS).

  5. To test, open notifier-queue, choose Send and receive messages, type a body, Send message, then Poll for messages. To redrive later, open notifier-dlq and choose Start DLQ redrive.

The same flow can run from AWS CloudShell, which already has credentials and the AWS CLI.

With the AWS CLI

export AWS_REGION=us-east-1
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

# Dead-letter queue first, with long retention (14 days = 1209600 seconds)
DLQ_URL=$(aws sqs create-queue --queue-name notifier-dlq \
  --attributes MessageRetentionPeriod=1209600 --query QueueUrl --output text)
DLQ_ARN=$(aws sqs get-queue-attributes --queue-url "$DLQ_URL" \
  --attribute-names QueueArn --query Attributes.QueueArn --output text)

# Source queue: visibility timeout, long polling and the redrive policy
cat > notifier-queue-attrs.json <<JSON
{
  "VisibilityTimeout": "180",
  "ReceiveMessageWaitTimeSeconds": "20",
  "RedrivePolicy": "{\"deadLetterTargetArn\":\"$DLQ_ARN\",\"maxReceiveCount\":\"5\"}"
}
JSON
QUEUE_URL=$(aws sqs create-queue --queue-name notifier-queue \
  --attributes file://notifier-queue-attrs.json --query QueueUrl --output text)

# Send, receive, delete
aws sqs send-message --queue-url "$QUEUE_URL" \
  --message-body '{"orderId":"o-1001","email":"reader@example.com"}'
aws sqs receive-message --queue-url "$QUEUE_URL" --wait-time-seconds 10 \
  --max-number-of-messages 5 --query 'Messages[].[MessageId,ReceiptHandle,Body]' --output text
aws sqs delete-message --queue-url "$QUEUE_URL" --receipt-handle "<receipt-handle>"

# FIFO queue: name ends in .fifo, content-based deduplication on
aws sqs create-queue --queue-name orders.fifo \
  --attributes FifoQueue=true,ContentBasedDeduplication=true
aws sqs send-message --queue-url "https://sqs.$AWS_REGION.amazonaws.com/$ACCOUNT_ID/orders.fifo" \
  --message-body '{"orderId":"o-1001","status":"PLACED"}' --message-group-id o-1001

# Redrive dead-lettered messages back to their source queue
aws sqs start-message-move-task --source-arn "$DLQ_ARN"
aws sqs list-message-move-tasks --source-arn "$DLQ_ARN"

Using SQS from Java

With Spring Boot, the Spring Cloud AWS SQS starter (io.awspring.cloud:spring-cloud-aws-starter-sqs, from the Spring Cloud AWS 4.x BOM for Boot 4 or 3.4.x for Boot 3.5) provides SqsTemplate for sending and @SqsListener for consuming. The credentials come from the default provider chain (task role, Pod Identity, instance profile), never from properties; only the Region needs configuring (spring.cloud.aws.region.static=us-east-1).

package com.example.bookshelf.notifier;

import io.awspring.cloud.sqs.annotation.SqsListener;
import io.awspring.cloud.sqs.operations.SqsTemplate;
import org.springframework.stereotype.Component;

@Component
public class OrderQueue {

    private final SqsTemplate sqs;

    public OrderQueue(SqsTemplate sqs) {
        this.sqs = sqs;
    }

    /** Producer side: send a JSON-serialisable payload to the queue. */
    public void enqueue(OrderPlaced event) {
        sqs.send(to -> to.queue("notifier-queue").payload(event));
    }

    /**
     * Consumer side: the message is deleted only if the method returns normally, so an exception
     * makes it visible again after the visibility timeout and eventually moves it to the DLQ.
     */
    @SqsListener("notifier-queue")
    public void onOrderPlaced(OrderPlaced event) {
        // must be idempotent: the same message can be delivered more than once
        sendConfirmationEmail(event);
    }

    private void sendConfirmationEmail(OrderPlaced event) {
        // see the SES page for the sending code
    }

    public record OrderPlaced(String orderId, String email) { }
}

This is the container alternative to the Lambda notifier: the same queue can be consumed by an ECS service or an EKS deployment, and scaled on queue depth (Application Auto Scaling on ECS, KEDA on EKS; see ECS deployments, scaling and networking and EKS microservices). For Quarkus, the SmallRye Reactive Messaging connectors in Messaging with SmallRye Reactive Messaging speak Kafka, AMQP and JMS, which maps to MSK and Amazon MQ below; for SQS itself use the Quarkiverse Amazon SQS extension or the AWS SDK client directly. Spring’s view of messaging is in Spring Boot messaging overview. See the Spring Cloud AWS reference.

Amazon SNS

Amazon Simple Notification Service publishes a message to a topic and delivers a copy to every subscription. Subscriber protocols include SQS queues, Lambda functions, Amazon Data Firehose, HTTP(S) endpoints, email, and SMS or mobile push (the latter through the AWS End User Messaging service, which replaces Amazon Pinpoint, whose end of support is 2026-10-30). Topics are standard (high throughput, at-least-once, best-effort ordering) or FIFO (ordering and deduplication, with SQS FIFO queues as subscribers; message archiving and replay are available for FIFO topics).

The pattern that matters most for application decoupling is SNS-to-SQS fan-out: the topic is the single publish point, each consumer owns an SQS queue subscribed to it, and a slow or failing consumer never affects the others because each queue buffers and dead-letters independently.

  • Filter policies let a subscriber receive only the messages it wants. A policy matches on message attributes (the default scope) or, with the MessageBody filter policy scope, on fields of a JSON body. Messages that do not match are not delivered and are not billed as deliveries to that subscriber.

  • Raw message delivery (RawMessageDelivery=true) delivers the original body to SQS instead of an SNS JSON envelope, so a consumer can read the same payload whether it came from the topic or was sent straight to the queue.

  • The queue needs a resource policy that allows the topic to send to it; without it the subscription is created but nothing arrives.

  • The maximum SNS message size is 256 KiB (checked 2026-10-01; the SNS Extended Client Library handles larger payloads through S3), and a PublishBatch call accepts 10 messages.

In the AWS Management Console

  1. Open Amazon SNS, then Topics, Create topic, choose Standard, name it bookshelf-order-events and create it.

  2. In the queue’s own console page (Amazon SQS, notifier-queue), open the SNS subscriptions tab and choose Subscribe to Amazon SNS topic, select bookshelf-order-events, and save. The console also adds the access policy. (Alternatively, in SNS open the topic, Create subscription, protocol Amazon SQS, endpoint the queue ARN.)

  3. Open the subscription, choose Edit, enable Raw message delivery, and under Subscription filter policy paste {"eventType": ["OrderPlaced"]} with scope Message attributes.

  4. Back on the topic, choose Publish message, add the message attribute eventType of type String with value OrderPlaced, a body, and Publish message; then poll the queue to see it arrive.

With the AWS CLI

TOPIC_ARN=$(aws sns create-topic --name bookshelf-order-events --query TopicArn --output text)
QUEUE_ARN=arn:aws:sqs:$AWS_REGION:$ACCOUNT_ID:notifier-queue

# Queue policy: only this topic may send to the queue
cat > queue-policy.json <<JSON
{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "AllowOrderEventsTopic",
    "Effect": "Allow",
    "Principal": { "Service": "sns.amazonaws.com" },
    "Action": "sqs:SendMessage",
    "Resource": "$QUEUE_ARN",
    "Condition": { "ArnEquals": { "aws:SourceArn": "$TOPIC_ARN" } }
  }]
}
JSON
aws sqs set-queue-attributes --queue-url "$QUEUE_URL" \
  --attributes "Policy=$(jq -c . queue-policy.json | jq -Rs .)"

# Subscribe with raw delivery and a filter policy on the eventType attribute
aws sns subscribe --topic-arn "$TOPIC_ARN" --protocol sqs --notification-endpoint "$QUEUE_ARN" \
  --attributes '{"RawMessageDelivery":"true","FilterPolicy":"{\"eventType\":[\"OrderPlaced\"]}"}'

# Publish with a message attribute
aws sns publish --topic-arn "$TOPIC_ARN" \
  --message '{"orderId":"o-1001","email":"reader@example.com"}' \
  --message-attributes '{"eventType":{"DataType":"String","StringValue":"OrderPlaced"}}'

The set-queue-attributes call replaces the whole queue policy, so merge any existing statements first. If the queue uses a customer managed KMS key, the key policy must also allow sns.amazonaws.com to use it, or messages are silently not delivered. References: aws sns create-topic, aws sns subscribe, aws sns publish, Fanout to Amazon SQS queues, SNS message filtering.

Publishing from Java

package com.example.bookshelf.orders;

import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.MessageAttributeValue;
import software.amazon.awssdk.services.sns.model.PublishRequest;

@Component
public class OrderEvents {

    private final SnsClient sns;
    private final String topicArn;

    public OrderEvents(SnsClient sns, @Value("${bookshelf.topic-arn}") String topicArn) {
        this.sns = sns;
        this.topicArn = topicArn;
    }

    public void orderPlaced(String json) {
        sns.publish(PublishRequest.builder()
                .topicArn(topicArn)
                .message(json)
                .messageAttributes(Map.of("eventType",
                        MessageAttributeValue.builder().dataType("String").stringValue("OrderPlaced").build()))
                .build());
    }
}

SnsClient comes from the Spring Cloud AWS SNS starter or from SnsClient.create(), and uses the default credential chain; the task or pod role needs sns:Publish on the topic ARN.

Amazon EventBridge

Amazon EventBridge is a serverless event router. It has four parts that are easy to confuse:

Part What it does

Event buses

Receive events and deliver them to targets. Every account has a default bus that receives events from AWS services; you create custom buses for your own application events and for cross-account sharing

Pipes

Connect one source (SQS, Kinesis, DynamoDB Streams, MSK and others) to one target, with optional filtering, enrichment and transformation

Scheduler

Runs one-time or recurring invocations of targets at a time or rate

Archive and replay

Stores events from a bus so they can be replayed later (Classic buses)

Event buses: Classic and the Custom Event Bus

EventBridge now offers two kinds of custom bus, and the official guide recommends starting with the newer one for new applications (checked 2026-10-01). Custom Event Bus - Classic is the long-standing bus: the bus owner writes rules with event patterns that send matching events to up to five targets each; events are not retained (use an archive to keep them). The Custom Event Bus keeps every event for a retention period you choose (1 to 365 days), lets each consuming team or account create its own subscribers (a filter, an optional transformation and exactly one target) on a bus shared through AWS Resource Access Manager, supports ordered (FIFO) delivery per event group, deduplication at publish time and a starting position for each subscriber, which gives replay without a separate archive. Both share the events: IAM namespace and the events.amazonaws.com principal. The default bus, which receives AWS service events, remains a Classic-style bus.

Capability Custom Event Bus - Classic Custom Event Bus

Routing

Rules owned by the bus owner, up to five targets per rule

Subscribers owned by each consumer, one target each

Retention and replay

None built in; add an archive and replay from it

Built-in retention (1 to 365 days) and a per-subscriber starting position

Ordering

Not available

FIFO per event group, per subscriber

Cross-account

Bus resource policy or forwarding to a bus in the other account

Share the bus with AWS RAM; each account attaches its subscribers

CLI namespace

aws events

aws eventsv2

Older guides and tutorials show only the Classic bus and rules (and the former name CloudWatch Events); those still work, and the Lambda page’s rule examples use them. Use Classic when you need the default bus (AWS service events such as EC2 state changes or CloudTrail events) or when you have rules already, and the Custom Event Bus for a new shared application bus.

In the AWS Management Console

  1. Open Amazon EventBridge, then Event buses, Create event bus, and choose the bus type (Custom Event Bus for the newer model or Custom Event Bus - Classic), name it bookshelf, and create it.

  2. For a Classic bus open Rules, Create rule, pick the bookshelf bus, write an event pattern for source bookshelf.orders and detail type OrderPlaced, and choose Amazon SQS queue notifier-queue as the target; let the console create the execution role. For the Custom Event Bus open the bus, Subscribers, Create subscriber, set the filter and choose the target.

  3. To test, open the bus and choose Send events, using the same source and detail type.

With the AWS CLI

# Classic bus, rule and SQS target
aws events create-event-bus --name bookshelf
aws events put-rule --event-bus-name bookshelf --name order-placed \
  --event-pattern '{"source":["bookshelf.orders"],"detail-type":["OrderPlaced"]}'
aws events put-targets --event-bus-name bookshelf --rule order-placed \
  --targets "Id=notifier,Arn=arn:aws:sqs:$AWS_REGION:$ACCOUNT_ID:notifier-queue"
# The queue needs a policy allowing events.amazonaws.com to send, with aws:SourceArn set to the rule ARN
aws events put-events --entries \
  '[{"EventBusName":"bookshelf","Source":"bookshelf.orders","DetailType":"OrderPlaced","Detail":"{\"orderId\":\"o-1001\"}"}]'

# Custom Event Bus (new): 30 days of retention and one subscriber delivering to an SQS queue
BUS_ARN=$(aws eventsv2 create-event-bus --name orders \
  --storage-configuration RetentionPeriodInDays=30 --query EventBusArn --output text)
aws eventsv2 create-subscriber --name large-orders --event-bus-arn "$BUS_ARN" \
  --filter-configuration '{"Filters":[{"Scope":"DATA","Pattern":"{\"detail\":{\"total\":[{\"numeric\":[\">\",500]}]}}"}]}' \
  --invoke-configuration "{\"TargetArn\":\"arn:aws:sqs:$AWS_REGION:$ACCOUNT_ID:large-orders\",\"RoleArn\":\"arn:aws:iam::$ACCOUNT_ID:role/EventBusDeliveryRole\"}"

The delivery role must trust events.amazonaws.com and allow sqs:SendMessage on the target (and on the subscriber’s dead-letter queue, if you configure --on-failure-configuration). A publish response only confirms that the bus accepted the event; check the target and the bus metrics to confirm delivery. References: aws events put-rule, aws events put-targets, aws events put-events, aws eventsv2 create-event-bus, aws eventsv2 create-subscriber, Custom Event Bus.

EventBridge Pipes

A pipe is the lightest way to move data between two AWS services: you choose a source, an optional filter, an optional enrichment step (a Lambda function, a Step Functions state machine, an API destination or API Gateway) and a target. You pay only for events that pass the filter. A typical Bookshelf use is a pipe from the DynamoDB stream of the Orders table (see DynamoDB) to an event bus, so that every inserted order becomes an OrderPlaced event without any application code:

aws pipes create-pipe --name orders-stream-to-bus \
  --role-arn "arn:aws:iam::$ACCOUNT_ID:role/orders-pipe-role" \
  --source "$ORDERS_STREAM_ARN" \
  --source-parameters '{"DynamoDBStreamParameters":{"StartingPosition":"LATEST","BatchSize":10},"FilterCriteria":{"Filters":[{"Pattern":"{\"eventName\":[\"INSERT\"]}"}]}}' \
  --target "arn:aws:events:$AWS_REGION:$ACCOUNT_ID:event-bus/bookshelf"

The pipe role needs read permissions on the source (dynamodb:DescribeStream, GetRecords, GetShardIterator, ListStreams) and events:PutEvents on the target, and trusts pipes.amazonaws.com. In the console use EventBridge, Pipes, Create pipe. References: aws pipes create-pipe, EventBridge Pipes.

EventBridge Scheduler

Scheduler is the managed way to run something later or repeatedly: one-time schedules, rate and cron expressions, time zones, flexible time windows, retry policies and a DLQ per schedule, with templated targets for many AWS APIs. It is the preferred replacement for scheduled rules in new work. The Lambda page shows a schedule that invokes a function; this one sends a reminder message to the notifier queue every morning through the universal SQS target:

aws scheduler create-schedule --name daily-digest \
  --schedule-expression "cron(0 8 * * ? *)" --schedule-expression-timezone "Europe/Madrid" \
  --flexible-time-window Mode=OFF \
  --target "{\"Arn\":\"arn:aws:scheduler:::aws-sdk:sqs:sendMessage\",\"RoleArn\":\"arn:aws:iam::$ACCOUNT_ID:role/scheduler-send-to-sqs\",\"Input\":\"{\\\"QueueUrl\\\":\\\"$QUEUE_URL\\\",\\\"MessageBody\\\":\\\"{\\\\\\\"type\\\\\\\":\\\\\\\"digest\\\\\\\"}\\\"}\"}"

The role trusts scheduler.amazonaws.com and allows sqs:SendMessage on the queue. For brevity the quoting above is the awkward part of the shell, not of Scheduler: prefer --target file://target.json in scripts. References: aws scheduler create-schedule, EventBridge Scheduler User Guide.

AWS Step Functions

Step Functions runs state machines defined in Amazon States Language: tasks that call AWS services directly (more than 200 integrations, including SQS, SNS, EventBridge, DynamoDB and Lambda), choices, parallel branches, maps, waits, retries and catches. Use it when a flow has several steps whose order, retries or compensation matter, instead of chaining queues and functions by hand. The Lambda page gives a minimal order-flow definition and compares Step Functions with Lambda durable functions; this page only covers where it sits among the messaging services.

Aspect Standard workflows Express workflows

Maximum duration

One year

Five minutes

Execution semantics

Exactly-once state execution

At-least-once (asynchronous) or at-most-once (synchronous)

Pricing model

Per state transition

Per execution, duration and memory

Callbacks and .sync integrations

Supported

Not supported

Use for

Long-running, auditable, non-idempotent flows (payments, fulfilment)

High-volume, short, idempotent event processing

The workflow type cannot be changed after creation. A state can send a message with the optimized SQS integration (arn:aws:states:::sqs:sendMessage) and can wait for an external system with the callback pattern (arn:aws:states:::sqs:sendMessage.waitForTaskToken, Standard only). In the console use Step Functions, State machines, Create state machine; from the CLI, aws stepfunctions create-state-machine. References: Step Functions Developer Guide, Choosing workflow type, aws stepfunctions create-state-machine.

Brokers and streams, briefly

Amazon MQ

Amazon MQ runs managed Apache ActiveMQ Classic and RabbitMQ brokers, so applications written for JMS, AMQP, MQTT, STOMP or OpenWire can move to AWS without code changes. You choose an instance size and a deployment mode (single instance for development, or a multi-Availability-Zone broker for production: active/standby for ActiveMQ and a three-node cluster for RabbitMQ, where quorum queues replicate across Availability Zones). Brokers live in your VPC and are billed by the hour for the broker instance plus storage, which is the main cost difference from the serverless services above. Prefer SQS and SNS for new AWS-native applications; prefer Amazon MQ when the application already depends on a broker’s protocol or features. The RabbitMQ model is documented on this site in RabbitMQ architecture and the AMQP model and RabbitMQ queue types; Spring and JMS usage in Spring Boot RabbitMQ and other Spring messaging options. CLI: aws mq; guide: What is Amazon MQ?.

Amazon MSK

Amazon Managed Streaming for Apache Kafka runs open-source Apache Kafka, so existing clients, Kafka Connect and Kafka Streams applications work unchanged. MSK Provisioned offers Standard brokers and Express brokers (faster scaling and recovery, a managed-storage model); MSK Serverless removes broker sizing; MSK Connect runs Kafka Connect connectors and MSK Replicator replicates between clusters. Clusters are created in your VPC and authenticated with IAM access control, SASL/SCRAM or mutual TLS. Supported versions move quickly: as checked on 2026-10-01 the documentation lists 3.9.x as the recommended version, 4.0.x and 4.1.x for provisioned clusters, and 4.2.x on Express brokers only, while 3.7.x reached end of support on 2026-09-01, so plan upgrades rather than pinning an old version. MSK is also a Lambda event source (see the Lambda page). Kafka itself is covered in depth on this site, starting at Kafka architecture, with producers, consumers, security and Spring Boot Kafka; Kafka versus RabbitMQ helps choose. Guide: Amazon MSK Developer Guide.

Amazon Kinesis

Kinesis Data Streams is AWS’s native partitioned log. A stream is a set of shards; each shard accepts up to 1 MB/s or 1,000 records per second in and serves 2 MB/s out, a record’s data blob is up to 1 MB, and records are routed to shards by partition key. Capacity is either on-demand (AWS manages the shards) or provisioned (you set the shard count). Retention is 24 hours by default and up to 365 days at extra charge. Consumers either share the read throughput of a shard or use enhanced fan-out for dedicated throughput. Typical Bookshelf use would be a click stream from the web front end:

aws kinesis create-stream --stream-name bookshelf-clicks \
  --stream-mode-details StreamMode=ON_DEMAND
aws kinesis put-record --stream-name bookshelf-clicks --partition-key session-42 \
  --data "$(echo '{"page":"/books/1"}' | base64)"

Amazon Data Firehose (formerly Kinesis Data Firehose) is the no-code delivery service from a stream or direct puts to S3, Apache Iceberg tables, OpenSearch, Redshift and HTTP endpoints, with buffering and optional transformation. The former Kinesis Data Analytics is now Managed Service for Apache Flink; its legacy SQL applications were shut down on 2026-01-27. Analytics services around these are introduced in AI, data and analytics overview. References: Kinesis Data Streams concepts, aws kinesis, What is Amazon Data Firehose?.

Security

  • Identity. Producers need sqs:SendMessage or sns:Publish on specific ARNs, consumers sqs:ReceiveMessage, sqs:DeleteMessage and sqs:GetQueueAttributes; grant them to task, function or pod roles (see Identity and access). Use resource policies, always with an aws:SourceArn or aws:SourceAccount condition, when an AWS service (SNS, EventBridge, S3) sends to a queue.

  • Encryption. SQS encrypts at rest by default with SQS-owned keys; use a customer managed KMS key when you need key policies or CloudTrail visibility of use, and remember that every service publishing to such a queue needs kms:GenerateDataKey and kms:Decrypt. SNS, EventBridge, Kinesis and MSK also support KMS.

  • Network. All of these have public endpoints; use interface VPC endpoints (AWS PrivateLink) from private subnets so traffic does not need a NAT gateway (see VPC networking). MSK and Amazon MQ brokers live inside your VPC.

  • Poison messages. A malformed message that always fails will cycle until it reaches the DLQ; make handlers distinguish permanent from transient errors and alarm on the DLQ.

Pricing model

Prices differ by Region and change over time, so use the dated pricing pages Amazon SQS pricing, Amazon SNS pricing, Amazon EventBridge pricing, AWS Step Functions pricing, Amazon MSK pricing, Amazon MQ pricing and Kinesis Data Streams pricing (all checked 2026-10-01), and model your workload in AWS Pricing Calculator. The cost drivers:

Service What you pay for

SQS

Requests (every send, receive and delete; a 64 KiB chunk of payload counts as one request unit), so long polling and batching of up to 10 messages reduce cost; data transfer out; a monthly free tier; FIFO requests cost more than standard

SNS

Publishes, deliveries by protocol (SQS and Lambda deliveries are cheap, SMS and mobile push are not), payload size, and data transfer out

EventBridge

Custom and partner events published to a bus, events delivered to API destinations, Pipes events that pass the filter, Scheduler invocations, and archive storage or Custom Event Bus retention; AWS service events on the default bus are free

Step Functions

Standard: state transitions. Express: executions, duration and memory

MSK

Broker hours, storage, data transfer between Availability Zones for Standard brokers, and provisioned throughput on Express brokers; Serverless and Connect are billed on their own dimensions

Amazon MQ

Broker instance hours and storage, plus data transfer

Kinesis

On-demand: per GB written and read; provisioned: shard hours and PUT payload units; extended retention and enhanced fan-out cost extra

The common surprises: a consumer that short-polls an empty queue all day pays for empty receives; a retry storm multiplies request charges; an MSK or Amazon MQ broker costs the same idle as busy; and a Standard Step Functions loop that transitions through many states per item costs far more than the same logic in an Express workflow.

Limits, recent changes and where older material differs

  • SQS maximum message size is 1 MiB (it was 256 KiB until 2025); SNS is still 256 KiB; Kinesis records are up to 1 MB.

  • The EventBridge Custom Event Bus with built-in retention, ordered delivery and subscribers is documented alongside the Classic bus (checked 2026-10-01), and the guide now recommends it for new applications; older tutorials describe only Classic buses, rules and the name CloudWatch Events.

  • Amazon Pinpoint reaches end of support on 2026-10-30; use SES for email and AWS End User Messaging for SMS and push.

  • Kinesis Data Firehose is now Amazon Data Firehose; Kinesis Data Analytics is now Managed Service for Apache Flink.

  • MSK clusters on Apache Kafka 3.7.x reached end of support on 2026-09-01; Kafka 3.9.x is the recommended version.

  • Older guides recommend polling SQS from EC2 fleets scaled by hand; Lambda event source mappings, ECS or EKS with queue-based scaling, and EventBridge Pipes remove most of that code today.

  • Quotas (queue and topic counts, in-flight messages, rules and subscribers per bus) are in the Service Quotas console and the quota pages linked below; several are adjustable.

Clean up

Delete subscriptions and sources before the resources they point to, and remove queues last.

aws pipes delete-pipe --name orders-stream-to-bus
aws scheduler delete-schedule --name daily-digest
aws events remove-targets --event-bus-name bookshelf --rule order-placed --ids notifier
aws events delete-rule --event-bus-name bookshelf --name order-placed
aws events delete-event-bus --name bookshelf
aws eventsv2 delete-subscriber --subscriber-arn "$SUBSCRIBER_ARN"
aws eventsv2 delete-event-bus --event-bus-arn "$BUS_ARN"
aws sns delete-topic --topic-arn "$TOPIC_ARN"      # deletes its subscriptions
aws sqs delete-queue --queue-url "$QUEUE_URL"
aws sqs delete-queue --queue-url "$DLQ_URL"
aws kinesis delete-stream --stream-name bookshelf-clicks

Deleting a queue is permanent and discards its messages, and a deleted queue name cannot be reused for 60 seconds. delete-event-bus for the Custom Event Bus succeeds only after every subscriber on it is deleted or revoked. Delete any MSK cluster (aws kafka delete-cluster) or Amazon MQ broker (aws mq delete-broker) you created while experimenting, since they bill by the hour.