The aws:sqs/queue:Queue resource, part of the Pulumi AWS provider, defines an SQS queue: its type (standard or FIFO), message handling behavior, encryption, and failure routing. This guide focuses on three capabilities: standard and FIFO queue configuration, message retention and delivery timing, and dead-letter routing and encryption options.
SQS queues act as message buffers between producers and consumers. They may reference dead-letter queues for failure routing and KMS keys for encryption. The examples are intentionally small. Combine them with your own access policies, Lambda triggers, and monitoring.
Configure a standard queue with message handling
Most deployments start with a standard queue that defines retention, delays, and dead-letter routing for failed messages.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const queue = new aws.sqs.Queue("queue", {
name: "example-queue",
delaySeconds: 90,
maxMessageSize: 2048,
messageRetentionSeconds: 86400,
receiveWaitTimeSeconds: 10,
redrivePolicy: JSON.stringify({
deadLetterTargetArn: queueDeadletter.arn,
maxReceiveCount: 4,
}),
tags: {
Environment: "production",
},
});
import pulumi
import json
import pulumi_aws as aws
queue = aws.sqs.Queue("queue",
name="example-queue",
delay_seconds=90,
max_message_size=2048,
message_retention_seconds=86400,
receive_wait_time_seconds=10,
redrive_policy=json.dumps({
"deadLetterTargetArn": queue_deadletter["arn"],
"maxReceiveCount": 4,
}),
tags={
"Environment": "production",
})
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/sqs"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
tmpJSON0, err := json.Marshal(map[string]interface{}{
"deadLetterTargetArn": queueDeadletter.Arn,
"maxReceiveCount": 4,
})
if err != nil {
return err
}
json0 := string(tmpJSON0)
_, err = sqs.NewQueue(ctx, "queue", &sqs.QueueArgs{
Name: pulumi.String("example-queue"),
DelaySeconds: pulumi.Int(90),
MaxMessageSize: pulumi.Int(2048),
MessageRetentionSeconds: pulumi.Int(86400),
ReceiveWaitTimeSeconds: pulumi.Int(10),
RedrivePolicy: pulumi.String(json0),
Tags: pulumi.StringMap{
"Environment": pulumi.String("production"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var queue = new Aws.Sqs.Queue("queue", new()
{
Name = "example-queue",
DelaySeconds = 90,
MaxMessageSize = 2048,
MessageRetentionSeconds = 86400,
ReceiveWaitTimeSeconds = 10,
RedrivePolicy = JsonSerializer.Serialize(new Dictionary<string, object?>
{
["deadLetterTargetArn"] = queueDeadletter.Arn,
["maxReceiveCount"] = 4,
}),
Tags =
{
{ "Environment", "production" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.sqs.Queue;
import com.pulumi.aws.sqs.QueueArgs;
import static com.pulumi.codegen.internal.Serialization.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var queue = new Queue("queue", QueueArgs.builder()
.name("example-queue")
.delaySeconds(90)
.maxMessageSize(2048)
.messageRetentionSeconds(86400)
.receiveWaitTimeSeconds(10)
.redrivePolicy(serializeJson(
jsonObject(
jsonProperty("deadLetterTargetArn", queueDeadletter.arn()),
jsonProperty("maxReceiveCount", 4)
)))
.tags(Map.of("Environment", "production"))
.build());
}
}
resources:
queue:
type: aws:sqs:Queue
properties:
name: example-queue
delaySeconds: 90
maxMessageSize: 2048
messageRetentionSeconds: 86400
receiveWaitTimeSeconds: 10
redrivePolicy:
fn::toJSON:
deadLetterTargetArn: ${queueDeadletter.arn}
maxReceiveCount: 4
tags:
Environment: production
When messages fail processing repeatedly, the redrivePolicy routes them to a dead-letter queue after maxReceiveCount attempts. The delaySeconds property postpones initial delivery, while receiveWaitTimeSeconds enables long polling to reduce empty responses. The messageRetentionSeconds property controls how long SQS keeps unprocessed messages before deletion.
Create a FIFO queue with content-based deduplication
Applications requiring strict ordering and exactly-once processing use FIFO queues, which guarantee messages are processed in arrival order.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const queue = new aws.sqs.Queue("queue", {
name: "example-queue.fifo",
fifoQueue: true,
contentBasedDeduplication: true,
});
import pulumi
import pulumi_aws as aws
queue = aws.sqs.Queue("queue",
name="example-queue.fifo",
fifo_queue=True,
content_based_deduplication=True)
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/sqs"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := sqs.NewQueue(ctx, "queue", &sqs.QueueArgs{
Name: pulumi.String("example-queue.fifo"),
FifoQueue: pulumi.Bool(true),
ContentBasedDeduplication: pulumi.Bool(true),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var queue = new Aws.Sqs.Queue("queue", new()
{
Name = "example-queue.fifo",
FifoQueue = true,
ContentBasedDeduplication = true,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.sqs.Queue;
import com.pulumi.aws.sqs.QueueArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var queue = new Queue("queue", QueueArgs.builder()
.name("example-queue.fifo")
.fifoQueue(true)
.contentBasedDeduplication(true)
.build());
}
}
resources:
queue:
type: aws:sqs:Queue
properties:
name: example-queue.fifo
fifoQueue: true
contentBasedDeduplication: true
Setting fifoQueue to true creates a FIFO queue, which requires the queue name to end with .fifo. The contentBasedDeduplication property enables automatic duplicate detection based on message body content, eliminating the need to provide explicit deduplication IDs.
Scale FIFO throughput per message group
High-volume FIFO workloads can partition throughput limits by message group rather than applying a single limit to the entire queue.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const queue = new aws.sqs.Queue("queue", {
name: "pulumi-example-queue.fifo",
fifoQueue: true,
deduplicationScope: "messageGroup",
fifoThroughputLimit: "perMessageGroupId",
});
import pulumi
import pulumi_aws as aws
queue = aws.sqs.Queue("queue",
name="pulumi-example-queue.fifo",
fifo_queue=True,
deduplication_scope="messageGroup",
fifo_throughput_limit="perMessageGroupId")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/sqs"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := sqs.NewQueue(ctx, "queue", &sqs.QueueArgs{
Name: pulumi.String("pulumi-example-queue.fifo"),
FifoQueue: pulumi.Bool(true),
DeduplicationScope: pulumi.String("messageGroup"),
FifoThroughputLimit: pulumi.String("perMessageGroupId"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var queue = new Aws.Sqs.Queue("queue", new()
{
Name = "pulumi-example-queue.fifo",
FifoQueue = true,
DeduplicationScope = "messageGroup",
FifoThroughputLimit = "perMessageGroupId",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.sqs.Queue;
import com.pulumi.aws.sqs.QueueArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var queue = new Queue("queue", QueueArgs.builder()
.name("pulumi-example-queue.fifo")
.fifoQueue(true)
.deduplicationScope("messageGroup")
.fifoThroughputLimit("perMessageGroupId")
.build());
}
}
resources:
queue:
type: aws:sqs:Queue
properties:
name: pulumi-example-queue.fifo
fifoQueue: true
deduplicationScope: messageGroup
fifoThroughputLimit: perMessageGroupId
The deduplicationScope property set to messageGroup and fifoThroughputLimit set to perMessageGroupId allow each message group to have its own throughput quota. This configuration increases total queue throughput when messages are distributed across multiple groups.
Enable encryption with SQS-managed keys
Queues handling sensitive data can enable server-side encryption using keys managed entirely by SQS.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const queue = new aws.sqs.Queue("queue", {
name: "pulumi-example-queue",
sqsManagedSseEnabled: true,
});
import pulumi
import pulumi_aws as aws
queue = aws.sqs.Queue("queue",
name="pulumi-example-queue",
sqs_managed_sse_enabled=True)
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/sqs"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := sqs.NewQueue(ctx, "queue", &sqs.QueueArgs{
Name: pulumi.String("pulumi-example-queue"),
SqsManagedSseEnabled: pulumi.Bool(true),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var queue = new Aws.Sqs.Queue("queue", new()
{
Name = "pulumi-example-queue",
SqsManagedSseEnabled = true,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.sqs.Queue;
import com.pulumi.aws.sqs.QueueArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var queue = new Queue("queue", QueueArgs.builder()
.name("pulumi-example-queue")
.sqsManagedSseEnabled(true)
.build());
}
}
resources:
queue:
type: aws:sqs:Queue
properties:
name: pulumi-example-queue
sqsManagedSseEnabled: true
Setting sqsManagedSseEnabled to true encrypts messages at rest using SQS-owned keys. This requires no KMS configuration or key management, making it the simplest encryption option.
Encrypt messages with customer-managed KMS keys
Organizations with strict compliance requirements can use customer-managed KMS keys for encryption, enabling audit trails and key rotation.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const queue = new aws.sqs.Queue("queue", {
name: "example-queue",
kmsMasterKeyId: "alias/aws/sqs",
kmsDataKeyReusePeriodSeconds: 300,
});
import pulumi
import pulumi_aws as aws
queue = aws.sqs.Queue("queue",
name="example-queue",
kms_master_key_id="alias/aws/sqs",
kms_data_key_reuse_period_seconds=300)
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/sqs"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := sqs.NewQueue(ctx, "queue", &sqs.QueueArgs{
Name: pulumi.String("example-queue"),
KmsMasterKeyId: pulumi.String("alias/aws/sqs"),
KmsDataKeyReusePeriodSeconds: pulumi.Int(300),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var queue = new Aws.Sqs.Queue("queue", new()
{
Name = "example-queue",
KmsMasterKeyId = "alias/aws/sqs",
KmsDataKeyReusePeriodSeconds = 300,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.sqs.Queue;
import com.pulumi.aws.sqs.QueueArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var queue = new Queue("queue", QueueArgs.builder()
.name("example-queue")
.kmsMasterKeyId("alias/aws/sqs")
.kmsDataKeyReusePeriodSeconds(300)
.build());
}
}
resources:
queue:
type: aws:sqs:Queue
properties:
name: example-queue
kmsMasterKeyId: alias/aws/sqs
kmsDataKeyReusePeriodSeconds: 300
The kmsMasterKeyId property specifies which KMS key to use for encryption. The kmsDataKeyReusePeriodSeconds property controls how long SQS reuses a data key before requesting a new one from KMS, balancing security with KMS API costs.
Beyond these examples
These snippets focus on specific queue-level features: standard and FIFO queue types, message handling (delays, retention, long polling), and dead-letter routing and encryption. They’re intentionally minimal rather than full messaging systems.
The examples may reference pre-existing infrastructure such as dead-letter queues for failure routing and KMS keys for customer-managed encryption. They focus on configuring the queue rather than provisioning everything around it.
To keep things focused, common queue patterns are omitted, including:
- Queue access policies (use aws.sqs.QueuePolicy resource)
- Redrive allow policies (use aws.sqs.RedriveAllowPolicy resource)
- Visibility timeout tuning (visibilityTimeoutSeconds)
- Message size limits (maxMessageSize)
These omissions are intentional: the goal is to illustrate how each queue feature is wired, not provide drop-in messaging modules. See the SQS Queue resource reference for all available configuration options.
Let's create and Configure SQS Queues
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Queue Policy & Timeouts
aws.sqs.QueuePolicy if the policy doesn’t explicitly include Version = "2012-10-17". Always set this version in your policy document to avoid timeouts.maxReceiveCount in redrivePolicy, you must use an integer (5), not a string (“5”). Using a string value causes the configuration to fail.Queue Types & Naming
fifoQueue to true and ensure the queue name ends with the .fifo suffix (e.g., “example-queue.fifo”). FIFO queue names must follow this naming convention.name to specify an exact queue name, or namePrefix to generate a unique name with your specified prefix. These properties conflict; you can only use one.name, namePrefix, and fifoQueue properties are immutable. You cannot rename a queue or convert between standard and FIFO types after creation.Dead Letter Queues
redrivePolicy with two properties: deadLetterTargetArn (the ARN of your dead letter queue) and maxReceiveCount (an integer specifying retry attempts before moving to DLQ). For example: redrivePolicy: JSON.stringify({ deadLetterTargetArn: dlq.arn, maxReceiveCount: 4 }).Message Configuration
delaySeconds to delay delivery of all messages in the queue. You can delay from 0 to 900 seconds (15 minutes), with a default of 0 (no delay).Encryption & Security
sqsManagedSseEnabled to true for SQS-owned keys) or SSE-KMS (set kmsMasterKeyId to use a customer-managed key). SSE-KMS also supports kmsDataKeyReusePeriodSeconds (60 to 86,400 seconds, default 300).Performance & Throughput
receiveWaitTimeSeconds to a value between 1 and 20 seconds. The default is 0, which means short polling (immediate return). Long polling reduces empty responses and costs.deduplicationScope to messageGroup and fifoThroughputLimit to perMessageGroupId. This applies throughput quotas per message group instead of per queue.deduplicationScope controls where deduplication occurs: messageGroup (per message group) or queue (entire queue, the default). Use messageGroup for higher throughput in FIFO queues.contentBasedDeduplication to true to enable automatic deduplication based on message body content. This eliminates the need to provide explicit deduplication IDs for FIFO queues.Using a different cloud?
Explore messaging guides for other cloud providers: