Building an Event-Driven Order Processing System with Amazon SQS, AWS Lambda, and DynamoDB
Learn how to build a serverless order-processing workflow using Amazon SQS, AWS Lambda, and Amazon DynamoDB. This article explains asynchronous processing, service decoupling, failure handling, and the architecture behind the solution.
Building an Event-Driven Order Processing System with Amazon SQS, AWS Lambda, and DynamoDB
Modern applications often need to process large numbers of requests without making users wait for every background operation to complete. One effective approach is event-driven architecture, where applications communicate through events or messages instead of relying on tightly coupled components.
In this article, we will build a simple serverless order-processing system using:
- Amazon SQS — message queuing
- AWS Lambda — serverless compute
- Amazon DynamoDB — NoSQL database
The goal is to accept an order, place it into an SQS queue, process it asynchronously using Lambda, and store the result in DynamoDB.
Architecture
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌─────────────────┐
│ Client/App │
└────────┬────────┘
│
│ Order Request
▼
┌─────────────────┐
│ Amazon SQS │
│ Queue │
└────────┬────────┘
│
│ Message
▼
┌─────────────────┐
│ AWS Lambda │
│ Order Processor │
└────────┬────────┘
│
│ Store Order
▼
┌─────────────────┐
│ DynamoDB │
│ Orders Table │
└─────────────────┘The workflow is straightforward:
- A client sends an order.
- The order is placed into an Amazon SQS queue.
- AWS Lambda receives the message.
- Lambda processes the order.
- The processed order is stored in DynamoDB.
The client does not need to wait for the complete background processing operation.
Why Use Amazon SQS?
Amazon Simple Queue Service (SQS) is a fully managed message queuing service.
Without a queue, an application might directly invoke a processing service:
1
Application → Lambda → DatabaseThis creates tighter coupling between the components.
With SQS, the architecture becomes:
1
Application → SQS → Lambda → DatabaseThe queue acts as a buffer between the producer and consumer.
This provides several advantages:
- Asynchronous processing
- Loose coupling between components
- Better fault isolation
- Message durability
- Independent scaling of application components
Step 1: Create an SQS Queue
Open the Amazon SQS console and create a queue.
For this example:
1
2
Queue name: OrderQueue
Queue type: StandardAfter creating the queue, keep its ARN available because it will be required when configuring Lambda.
A Standard queue is appropriate when strict ordering of every message is not a requirement.
Step 2: Create a DynamoDB Table
Create a DynamoDB table with the following configuration:
1
2
3
Table name: Orders
Partition key: orderId
Type: StringThe table will contain processed orders.
An example DynamoDB item could look like this:
1
2
3
4
5
6
7
{
"orderId": "ORD1001",
"customerName": "Sanjay",
"product": "Laptop",
"quantity": 1,
"status": "PROCESSED"
}Step 3: Create the Lambda Function
Create an AWS Lambda function using Python.
For example:
1
2
Function name: ProcessOrder
Runtime: Python 3.xThe Lambda function will receive messages from SQS and write the order information to DynamoDB.
Example implementation:
1
import jsonimport boto3dynamodb = boto3.resource("dynamodb")table = dynamodb.Table("Orders")def lambda_handler(event, context): for record in event["Records"]: message = json.loads(record["body"]) order_id = message["orderId"] customer_name = message["customerName"] product = message["product"] quantity = message["quantity"] table.put_item( Item={ "orderId": order_id, "customerName": customer_name, "product": product, "quantity": quantity, "status": "PROCESSED" } ) print(f"Processed order: {order_id}") return { "statusCode": 200, "body": "Orders processed successfully" }The function loops through the SQS records, extracts the order information, and stores each order in DynamoDB.
Step 4: Configure Lambda Permissions
The Lambda execution role needs permission to interact with the required AWS services.
At minimum, the function needs permissions to:
- Receive and process messages from SQS
- Write items to the DynamoDB table
For production applications, follow the principle of least privilege.
Avoid granting broad permissions such as:
1
2
dynamodb:*
sqs:*Instead, provide only the specific actions and resources required by the application.
Step 5: Connect SQS to Lambda
Create an event source mapping between the SQS queue and the Lambda function.
The relationship should look like:
1
2
3
4
5
6
7
8
9
Lambda
↓
ProcessOrder
↓
Add trigger
↓
Amazon SQS
↓
OrderQueueLambda can then poll the queue and invoke the function when messages are available.
This removes the need for the application to continuously check whether messages are ready for processing.
Step 6: Send a Test Message
Send the following message to the SQS queue:
1
2
3
4
5
6
{
"orderId": "ORD1001",
"customerName": "Sanjay",
"product": "Laptop",
"quantity": 1
}The processing flow becomes:
1
2
3
4
5
6
7
8
9
Order Message
↓
SQS Queue
↓
Lambda Trigger
↓
Process Message
↓
DynamoDBAfter successful processing, the order should appear in the DynamoDB table.
Handling Failed Messages
Distributed systems need to account for failures.
If Lambda cannot successfully process a message, SQS can make the message available for another processing attempt.
For applications requiring stronger failure handling, configure a Dead-Letter Queue (DLQ).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──────────────┐
│ SQS Queue │
└──────┬───────┘
│
▼
┌──────────────┐
│ Lambda │
└──────┬───────┘
│
Processing
fails
│
▼
┌──────────────┐
│ Dead-Letter │
│ Queue │
└──────────────┘A DLQ allows failed messages to be isolated and investigated instead of retrying them indefinitely.
Why This Architecture Works
The main benefit of this architecture is decoupling.
The producer does not need to know how the consumer processes the order.
1
2
3
4
5
6
7
8
9
10
Producer
│
▼
SQS
│
▼
Consumer
│
▼
DynamoDBEach component has a clear responsibility:
- The application produces orders.
- SQS manages messages.
- Lambda processes orders.
- DynamoDB stores the results.
This makes individual components easier to modify and scale.
Real-World Use Cases
The same architecture can be applied to many workloads, including:
- E-commerce order processing
- Email notification systems
- Image processing
- Log processing
- Data ingestion
- Background jobs
- IoT event processing
- Report generation
For example, an e-commerce application could use:
1
2
3
4
5
6
7
8
9
Customer places order
↓
SQS
↓
Lambda
↓
┌────┴────┐
↓ ↓
DynamoDB NotificationThe customer-facing application can remain responsive while background operations are processed asynchronously.
Security Considerations
When implementing this architecture in production:
- Use IAM roles instead of hard-coded AWS credentials.
- Follow the principle of least privilege.
- Encrypt sensitive data where required.
- Enable appropriate SQS encryption.
- Protect sensitive information stored in DynamoDB.
- Monitor Lambda execution using Amazon CloudWatch.
- Configure appropriate SQS visibility timeout and retry behavior.
- Use a Dead-Letter Queue for messages that repeatedly fail.
Cost Considerations
One advantage of this architecture is that the services are fully managed. There is no need to maintain a dedicated server just to process background jobs.
However, the overall cost depends on factors such as:
- Number of SQS requests
- Lambda invocations and execution duration
- DynamoDB read and write usage
- Data transfer
- Logging and monitoring
For low-volume applications, serverless services can be an efficient way to run background workloads without maintaining continuously running infrastructure.
Conclusion
Event-driven architecture provides a practical way to build scalable and loosely coupled applications.
By combining Amazon SQS, AWS Lambda, and Amazon DynamoDB, we can create an order-processing system in which:
1
2
3
4
5
6
7
Application
↓
SQS
↓
Lambda
↓
DynamoDBSQS provides asynchronous messaging, Lambda handles processing without requiring servers, and DynamoDB provides scalable NoSQL storage.
This pattern can be extended to many real-world workloads and provides a solid foundation for building modern event-driven applications on AWS.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article