AWS Step Functions: State Machine Design & ASL Guide
Step Functions orchestrates complex workflows across AWS services with built-in error handling, retries, and visual debugging โ no coordination code in Lambda. This guide covers ASL syntax, all state types, error handling patterns, and workflow design best practices.
ASL State Machine: Complete Example
{
"Comment": "Order processing workflow",
"StartAt": "ValidateOrder",
"States": {
"ValidateOrder": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789:function:ValidateOrder",
"Retry": [
{
"ErrorEquals": ["Lambda.ServiceException", "Lambda.AWSLambdaException"],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2
}
],
"Catch": [
{
"ErrorEquals": ["ValidationError"],
"Next": "SendRejectionEmail",
"ResultPath": "$.error"
}
],
"Next": "ProcessPayment"
},
"ProcessPayment": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789:function:ProcessPayment",
"TimeoutSeconds": 30,
"Next": "CheckPaymentStatus"
},
"CheckPaymentStatus": {
"Type": "Choice",
"Choices": [
{ "Variable": "$.paymentStatus", "StringEquals": "SUCCESS", "Next": "FulfillOrder" },
{ "Variable": "$.paymentStatus", "StringEquals": "PENDING", "Next": "WaitForPayment" }
],
"Default": "SendFailureNotification"
},
"WaitForPayment": {
"Type": "Wait",
"Seconds": 300,
"Next": "CheckPaymentStatus"
},
"FulfillOrder": {
"Type": "Parallel",
"Branches": [
{
"StartAt": "UpdateInventory",
"States": {
"UpdateInventory": {
"Type": "Task",
"Resource": "arn:aws:states:::dynamodb:updateItem",
"Parameters": {
"TableName": "Inventory",
"Key": { "productId": { "S.$": "$.productId" } },
"UpdateExpression": "SET quantity = quantity - :qty",
"ExpressionAttributeValues": { ":qty": { "N.$": "$.quantity" } }
},
"End": true
}
}
},
{
"StartAt": "SendConfirmationEmail",
"States": {
"SendConfirmationEmail": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Parameters": {
"TopicArn": "arn:aws:sns:us-east-1:123456789:OrderConfirmations",
"Message.$": "States.Format('Order {} confirmed!', $.orderId)"
},
"End": true
}
}
}
],
"End": true
},
"SendRejectionEmail": { "Type": "Succeed" },
"SendFailureNotification": { "Type": "Fail", "Error": "PaymentFailed" }
}
} Standard vs Express Workflow Comparison
| Feature | Standard Workflow | Express Workflow |
|---|---|---|
| Max duration | 1 year | 5 minutes |
| Execution semantics | Exactly-once | At-least-once |
| Pricing | $0.025/1K transitions | $1.00/M executions + duration |
| Execution history | 90 days in console | CloudWatch Logs only |
| Throughput | 2,000 executions/sec | 100,000 executions/sec |
| Best for | Orders, approvals, long processes | High-volume event processing |
Map State: Process Arrays in Parallel
// Map state processes each item in an array concurrently
{
"ProcessOrders": {
"Type": "Map",
"ItemsPath": "$.orders", // Array to iterate
"MaxConcurrency": 10, // Max parallel branches
"Parameters": {
"orderId.$": "$$.Map.Item.Value.id",
"amount.$": "$$.Map.Item.Value.amount"
},
"Iterator": {
"StartAt": "ProcessSingleOrder",
"States": {
"ProcessSingleOrder": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789:function:ProcessOrder",
"End": true
}
}
},
"ResultPath": "$.processedOrders",
"Next": "SendSummary"
}
}
// Use case: process 100 orders in batches of 10 concurrently
// Much faster than sequential processing
// MaxConcurrency: 0 = unbounded parallelism Related Products
on GumroadDeveloper Productivity Bundle
Stop rebuilding the same setup every project. 51 VSCode snippets, 40 Git aliases, 5 Docker Compose stacks, 5 GitHub Actions workflows, 5 README templates, and a dotfiles kit. Set up a professional dev environment in under an hour.
Buy on Gumroad โAI Prompt Engineering Toolkit
58 structured prompt templates for Claude, ChatGPT, and Gemini โ organized by use case. Code Review, Debugging, Documentation, Architecture, and 10 model-specific tips. Stop writing prompts from scratch.
Buy on Gumroad โDeveloper Cheat Sheet Bundle
10 print-ready cheat sheets for the tools developers use every day: Git, Docker, Linux CLI, SQL, Regex, HTTP Status codes, VS Code shortcuts, Bash scripting, jq/JSON, and Markdown.
Buy on Gumroad โYou Might Also Need
AWS CDK Infrastructure as Code Guide
Complete AWS CDK guide for TypeScript/Python IaC. Learn constructs (L1/L2/L3), stacks, CDK Pipelines, diff/deploy workflow, and comparison with Terraform and CloudFormation.
Open free tool โ
AWS Lambda Cost Calculator
Estimate monthly AWS Lambda costs. Input invocations, duration, memory, and data transfer to get compute cost, request cost, and total with EC2 comparison.
Open free tool โ
AWS IAM Policy Generator
Visual AWS IAM policy JSON builder with action and resource selectors. Generate least-privilege IAM policies for S3, EC2, Lambda, DynamoDB, and more.
Open free tool โ
More Free Tools
Related Articles
AWS Lambda Cold Start Optimization: 10 Proven Techniques 2026
Eliminate or minimize AWS Lambda cold starts with 10 proven techniques: provisioned concurrency, SnapStart, package minimization, ARM Graviton2, lazy loading, and more with benchmark data.
Serverless vs Containers 2026: Lambda vs Docker Decision Guide
When should you use AWS Lambda vs Docker containers? This 2026 guide covers cost models, cold starts, use cases, hybrid architectures, and a decision flowchart to help you choose.
Cloud Deployment Tools in 2026: From Containers to Serverless
A practical guide to cloud deployment tools in 2026. Compare deployment strategies, container platforms, serverless frameworks, and GitOps workflows that enterprise teams use to ship software reliably.
Serverless vs Containers 2026: When to Use Each
Decision framework for choosing between serverless functions and containers in 2026. Cost analysis, cold start realities, architecture patterns, and the right tool for each workload type.
Serverless Cold Starts: How to Reduce Lambda Latency by 80%
Learn what causes AWS Lambda cold starts and how to reduce latency by 80%. Covers runtime comparison, Provisioned Concurrency, SnapStart, package optimization, and best practices.
Enjoying this tool? Get more like it.
Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.
Unlock AI-Powered Dev Tools
- โก AI Code Review, Doc Generator & SQL Builder
- โก All premium templates & early access
- โก Member discounts on Gumroad products
$9/mo after trial ยท Cancel anytime
Want the full toolkit?
Get DevPlaybook Pro
Every template, guide, boilerplate, and automation script in one bundle. 13 premium products โ grab them all at once and save big.
MIT licensed ยท Instant download ยท No subscription
See what's included โ Browse all deals โFrequently Asked Questions
What is AWS Step Functions?▼
AWS Step Functions is a serverless orchestration service that coordinates multiple AWS services (Lambda, DynamoDB, SQS, ECS, etc.) into a workflow defined in Amazon States Language (ASL). Instead of writing complex coordination logic inside Lambda functions, Step Functions manages state, retries, error handling, and parallel execution through a visual state machine. It is ideal for multi-step workflows, long-running processes, and distributed transactions.
What is the difference between Standard and Express workflows?▼
Standard workflows support execution durations up to 1 year, have exactly-once execution semantics, and store full execution history in the console. They cost $0.025 per 1,000 state transitions. Express workflows support durations up to 5 minutes, have at-least-once semantics, stream logs to CloudWatch, and cost $1.00 per million workflow requests plus duration. Use Standard for human-approval workflows and long processes; use Express for high-volume, short-duration event processing.
What are the main state types in ASL?▼
ASL has 8 state types: Task (call a service or Lambda), Choice (conditional branching, like if/else), Parallel (run branches concurrently), Map (iterate over array items), Wait (pause for a time or timestamp), Pass (transform input/output), Succeed (end execution successfully), and Fail (end with error). Combining these states covers virtually all workflow patterns.
How does error handling work in Step Functions?▼
Each Task state can have Retry and Catch blocks. Retry specifies retry intervals and backoff rates for specific error types (Lambda.ServiceException, States.Timeout, etc.). Catch routes execution to a fallback state when retries are exhausted. This declarative error handling means you do not need to write retry logic in Lambda code โ the state machine handles it, making workflows more resilient and easier to debug.
What is the Step Functions SDK integration and why use it?▼
SDK integrations (also called optimized integrations or direct integrations) allow Step Functions to call AWS services like DynamoDB, SQS, SNS, or EventBridge directly โ without needing a Lambda function as a wrapper. This reduces Lambda invocations, lowers cost, and improves reliability. For example, writing to DynamoDB from a workflow step is cheaper and simpler via SDK integration than via a Lambda function that calls DynamoDB.
When should I use Step Functions vs SQS vs EventBridge?▼
Step Functions is best when you need explicit workflow visualization, complex branching logic, error handling across multiple steps, or human approval steps. SQS is best for simple message queuing between decoupled services with a Lambda consumer. EventBridge is best for event-driven architectures where multiple services react to events independently. For orchestration (one service directs others), use Step Functions. For choreography (services independently react), use EventBridge or SQS.