Are your background tasks hanging under peak loads, and messages getting lost without a trace? Amazon SQS is a managed message queue that solves these problems without broker administration. SQS processes over 10,000 messages per second, stores them for up to 14 days, and scales automatically. 99.9% uptime SLA guarantees availability. We set up SQS for your web application turnkey: from design to deployment.
Unlike custom solutions, SQS requires no cluster setup or broker monitoring. You pay only for usage, saving up to $2000 per year on infrastructure (at 1 million messages/day load). With a queue, you avoid data loss during consumer failures — each message is stored for up to 14 days. Dead Letter Queue insures against unprocessed tasks.
Why SQS might be better than RabbitMQ?
RabbitMQ requires a dedicated server and manual cluster management. Redis Queue is fast but doesn't guarantee long-term persistence during failures. SQS is a fully managed service with automatic scaling, long-term storage (up to 14 days), and built-in Dead Letter Queue support. Performance-wise, SQS Standard handles thousands of messages per second, while FIFO up to 3000 (with batch sending). For most web applications, SQS is the optimal balance between simplicity and reliability. Setting up an SQS queue takes 3 times less time than deploying RabbitMQ.
| Queue Type | Throughput | Order Guarantee | Duplicates | Use Case |
|---|---|---|---|---|
| Standard | High (near unlimited) | No | Possible | Background tasks, logging, notifications |
| FIFO | Up to 3000 msg/s (with batch) | Yes | Excluded | Financial transactions, orders, audit |
How to configure Visibility Timeout and DLQ?
Visibility timeout — the time a message is hidden from other consumers after being received. Default is 30 seconds. If the message is not deleted within that time, it becomes visible again. Increase the timeout if processing takes longer than 30 seconds. For example, for payment processing with an external API, set 2-5 minutes. For tasks that may hang, use Dead Letter Queue: after 3 failed attempts, the message moves to DLQ. 95% of messages are processed on the first attempt with a properly set timeout.
Integration with your stack
Terraform (Infrastructure as Code)
Standard infrastructure code for replication in any environment, including Lambda binding:
# Dead Letter Queue
resource "aws_sqs_queue" "dlq" {
name = "myapp-jobs-dlq"
message_retention_seconds = 1209600 # 14 days
}
# Main queue
resource "aws_sqs_queue" "jobs" {
name = "myapp-jobs"
visibility_timeout_seconds = 300
message_retention_seconds = 86400
receive_wait_time_seconds = 20
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.dlq.arn
maxReceiveCount = 3
})
}
# FIFO queue (for tasks requiring order)
resource "aws_sqs_queue" "orders_fifo" {
name = "myapp-orders.fifo"
fifo_queue = true
content_based_deduplication = true
deduplication_scope = "messageGroup"
fifo_throughput_limit = "perMessageGroupId"
}
# IAM policy for application
resource "aws_iam_policy" "sqs_app" {
name = "myapp-sqs-access"
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = [
"sqs:SendMessage",
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes",
]
Resource = [aws_sqs_queue.jobs.arn, aws_sqs_queue.dlq.arn]
}]
})
}
# Lambda event source mapping
resource "aws_lambda_event_source_mapping" "sqs_lambda" {
event_source_arn = aws_sqs_queue.jobs.arn
function_name = aws_lambda_function.worker.arn
batch_size = 10
maximum_batching_window_in_seconds = 5
function_response_types = ["ReportBatchItemFailures"]
}
PHP: AWS SDK
Custom consumer for non-Laravel projects:
use Aws\Sqs\SqsClient;
class SqsQueue
{
private SqsClient $client;
private string $queueUrl;
public function __construct()
{
$this->client = new SqsClient([
'version' => 'latest',
'region' => config('aws.region', 'eu-west-1'),
]);
$this->queueUrl = config('queue.connections.sqs.queue');
}
public function send(string $jobClass, array $payload, int $delaySeconds = 0): string
{
$result = $this->client->sendMessage([
'QueueUrl' => $this->queueUrl,
'MessageBody' => json_encode([
'job' => $jobClass,
'payload' => $payload,
'attempts' => 0,
'sent_at' => now()->toIso8601String(),
]),
'DelaySeconds' => $delaySeconds,
'MessageAttributes' => [
'JobClass' => [
'DataType' => 'String',
'StringValue' => $jobClass,
],
],
]);
return $result['MessageId'];
}
public function poll(int $maxMessages = 10): void
{
$result = $this->client->receiveMessage([
'QueueUrl' => $this->queueUrl,
'MaxNumberOfMessages' => $maxMessages,
'WaitTimeSeconds' => 20,
'VisibilityTimeout' => 300,
]);
foreach ($result->get('Messages') ?? [] as $message) {
$this->processMessage($message);
}
}
private function processMessage(array $message): void
{
try {
$body = json_decode($message['Body'], true);
$job = app($body['job']);
$job->handle($body['payload']);
$this->client->deleteMessage([
'QueueUrl' => $this->queueUrl,
'ReceiptHandle' => $message['ReceiptHandle'],
]);
} catch (\Throwable $e) {
Log::error('SQS job failed', [
'job' => $body['job'] ?? 'unknown',
'error' => $e->getMessage(),
]);
}
}
}
Laravel Queue
Laravel supports SQS out of the box. Configuration via .env:
QUEUE_CONNECTION=sqs
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=secret
AWS_DEFAULT_REGION=eu-west-1
SQS_QUEUE=https://sqs.eu-west-1.amazonaws.com/123456789/myapp-jobs
And the Job class:
class ProcessOrderJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public int $timeout = 120;
public function __construct(private int $orderId) {}
public function handle(OrderService $service): void
{
$service->process($this->orderId);
}
public function failed(\Throwable $e): void
{
Log::error('Order processing failed', [
'order_id' => $this->orderId,
'error' => $e->getMessage(),
]);
}
}
ProcessOrderJob::dispatch($order->id);
ProcessOrderJob::dispatch($order->id)->delay(now()->addMinutes(5));
SQS + Lambda (serverless)
For event-driven architecture, use Lambda. Handler code in Python:
import json
def handler(event, context):
failed_ids = []
for record in event['Records']:
try:
body = json.loads(record['body'])
process_job(body)
except Exception as e:
print(f"Failed: {record['messageId']}: {e}")
failed_ids.append({'itemIdentifier': record['messageId']})
return {'batchItemFailures': [{'itemIdentifier': id} for id in failed_ids]}
Comparison of Integration Approaches
| Approach | Implementation Time | Complexity | Flexibility | Suitable For |
|---|---|---|---|---|
| Laravel Queue | 1 day | Low | Medium | Projects on Laravel |
| Custom PHP consumer | 2-3 days | Medium | High | Any PHP application |
| SQS + Lambda | 2-3 days | Medium | High | Event-driven / serverless |
Common Mistakes and Monitoring
- Too short visibility timeout leads to reprocessing. Always include a 30% buffer.
- Missing DLQ — message loss during consumer failures.
- Incorrect IAM policies — application can't send/receive messages.
- Monitoring not configured — queue depth grows unnoticed.
CloudWatch SQS metrics: ApproximateNumberOfMessagesVisible, NumberOfMessagesSent, NumberOfMessagesDeleted, ApproximateAgeOfOldestMessage. We recommend setting an alert on queue depth — e.g., when >1000 messages, send a Slack notification. AWS CloudWatch documentation recommends tracking these metrics for timely response.
How We Set Up SQS: Step-by-Step Process
- Analytics. Determine load, ordering and durability requirements.
- Design. Select queue type, configure visibility timeout, DLQ, IAM policies.
- Implementation. Write consumer (Laravel, custom PHP/Node.js) or Lambda triggers.
- Test. Perform load testing, verify fault tolerance.
- Deploy. Deploy via Terraform, configure CI/CD, set up CloudWatch alerts.
What's Included and Timelines
- Queue architecture documentation
- Terraform code for entire infrastructure
- Access rights and IAM policies
- Consumer with error handling and DLQ
- Monitoring (CloudWatch metrics + alerts)
- Team training on queue operation
- Post-launch support (1 month)
Timelines: Laravel Queue + SQS — 1 day. Custom PHP/Node.js consumer with DLQ and monitoring — 2-3 days. SQS + Lambda serverless — 2-3 days. Exact timelines are estimated after analyzing your project. We have been working with queues for over 5 years and have implemented 30+ projects. Get a consultation for your project right now. Order SQS setup and forget about queue issues.







