What Is AWS Step Functions? Use Cases and Workflow Types

AWS Step Functions is a workflow orchestration service that coordinates Lambda functions and AWS services into reliable, observable workflows called state machines. You define the steps, the order, the branching logic, and the error handling in a JSON workflow definition. Step Functions executes it durably and tracks every state transition. Use it when you have multi-step processes where reliability, visibility, and error handling matter. Skip it for simple one- or two-step logic that does not need workflow-level durability.

Simple explanation

Think of Step Functions as a flight operations board at an airport. Each flight (workflow execution) moves through a series of gates: check-in, security, boarding, departure. Each gate is a step. If a gate is delayed, the board knows which step is waiting and why. If something fails, it routes to a fallback procedure rather than losing track of the flight entirely.

Your Lambda functions are the workers at each gate. Step Functions is the board that knows where every execution is, what comes next, and what to do when things go wrong. Without Step Functions, that coordination logic lives in your application code, and it is usually fragile.

Why teams use AWS Step Functions

Multi-step workflows are harder to build reliably than they look. The problems compound quickly:

  • Partial failures. If step 3 of a 5-step workflow fails, where does it retry? Does step 2 run again? Does the workflow lose its place?
  • Long waits. Some workflows pause for hours or days waiting for a human approval or an external system. You cannot hold a Lambda function open for that.
  • Branching logic. Real workflows have conditions: if the payment failed, go here; if inventory is available, go there. Writing this in application code creates sprawling if/else chains across multiple services.
  • No visibility. When an ad hoc workflow fails at 3 AM, what ran? What failed? What was the input to the failing step? Logs from five separate Lambda functions do not answer this easily.

Step Functions solves all of these. It tracks state durably across steps, supports configurable retry and catch blocks at each step, handles waiting states that pause for free without consuming compute, and records every state transition so you can see exactly what happened to each execution.

It also removes orchestration logic from your Lambda functions. Each function does one job. The workflow definition controls the order, the branching, and the error routing. See event-driven compute with Lambda for how this fits into a broader event-driven architecture.

How AWS Step Functions works

State machines

A Step Functions workflow is defined as a state machine: a JSON document written in Amazon States Language (ASL). The state machine defines the states (steps), the transitions between them, and the error handling at each step. You create the state machine once and run it as many times as needed. Each run is an execution.

Mental model

A state machine is like a recipe. The recipe defines what to do at each step, what order to do it in, and what to do if something goes wrong. Executing the recipe is a separate thing from writing it. Step Functions separates these too: the state machine is the recipe; each execution is someone following it.

States

Each state is a step in the workflow. The main state types:

State typeWhat it does
TaskCalls a Lambda function, API, or other AWS service. The most common state type. Can call over 200 AWS services directly without a Lambda wrapper.
ChoiceBranches based on conditions in the input data. Like an if/else or switch statement in the workflow definition.
WaitPauses for a specified duration or until a timestamp. The execution is suspended. No compute is consumed during the wait.
ParallelRuns multiple branches simultaneously and waits for all branches to complete before continuing.
MapIterates over a list and runs a sub-workflow for each item. Items can be processed in parallel with a configurable concurrency limit.
PassPasses input to output without doing anything. Useful for transforming data or testing workflows.
Succeed / FailEnds the execution with a success or failure result.

Executions

When you start an execution, you pass an input JSON document. The execution runs from the StartAt state, moves through transitions, and ends when it reaches a Succeed or Fail state. Each Standard workflow execution is tracked individually. You can see the execution history, input, output, and any errors in the AWS console or via the API.

Input and output between steps

Each state receives JSON input and produces JSON output. The output of one state becomes the input of the next. You can use InputPath, OutputPath, and ResultSelector to filter and transform what gets passed between states, so you are not forwarding unnecessary data at every step.

Payload size limit

State payloads have a maximum size. For large data such as file contents or database query results, store the data in S3 or DynamoDB and pass only the reference key between states. Trying to pass large objects directly through state transitions will fail.

Retries, catch, and failure handling

Each Task state can have a Retry block that automatically retries on specified errors, with configurable intervals, maximum attempts, and backoff rate. A Catch block routes the execution to a different state when retries are exhausted, for example routing to a failure notification step rather than leaving the execution in a failed state with no recovery path.

Retry and catch logic is declarative and lives in the workflow definition, not scattered across multiple Lambda functions. This is one of the strongest reasons to use Step Functions over ad hoc orchestration in code.

Always add retry config

Lambda functions can fail transiently due to throttling, cold starts, or brief network issues. Add a Retry block for Lambda.ServiceException and Lambda.TooManyRequestsException with exponential backoff on every Task state. Without it, a single transient failure permanently terminates the execution.

Wait, parallel, and map states

Wait states are particularly useful for human-in-the-loop workflows. A workflow can pause waiting for a callback token: a unique identifier that an external system or human uses to resume the execution. The execution is suspended with no cost until the token is returned.

Parallel states run multiple independent branches simultaneously and merge the results. For example: validate the order, check for fraud, and verify inventory all at the same time rather than sequentially.

Map states process a list of items through the same sub-workflow in parallel. For example: send a personalised notification to each user in a list, or run the same transformation on each record in a batch file.

Visual workflows and direct service integrations

The AWS console renders state machines as an interactive graph. During a live execution, the console shows which state is currently active, which have completed, and which failed, giving you a real-time view of the workflow without needing to read logs.

Step Functions also has direct SDK integrations for over 200 AWS services, including DynamoDB, S3, SNS, SQS, ECS, and Glue. For many AWS API calls, you do not need a Lambda function. Call the service directly from a Task state. This reduces cost, latency, and the number of Lambda functions to maintain.

How an execution flows, step by step

  1. Start execution. You call StartExecution with an input JSON document and a unique execution name.
  2. Enter first state. The execution enters the StartAt state defined in the state machine.
  3. Task state runs. If the state is a Task, Step Functions invokes the configured Lambda function or AWS service call and waits for the result.
  4. Output is passed forward. The task result is filtered through OutputPath or ResultSelector and passed as input to the next state.
  5. Retries and catch. If the task fails, Step Functions checks the Retry configuration. If retries are exhausted, the Catch block routes to a fallback state.
  6. Transitions continue. The execution moves through Task, Choice, Wait, Parallel, and Map states until it reaches a terminal state.
  7. Execution ends. A Succeed or Fail state ends the execution. The full history, including every input, output, and state transition, is preserved for 90 days.

When to use AWS Step Functions

Step Functions is a good fit when:

  • You have multiple steps that depend on each other. The output of one step feeds the input of the next, and you need the workflow tracked durably.
  • Error handling and retries matter. Partial failures in multi-step processes are hard to recover from without explicit state tracking.
  • You need branching or conditional logic. If/else routing between steps based on data from previous steps.
  • The workflow may pause for a long time. Human approvals, waiting for an external system, or scheduled continuations. Wait states handle this without holding compute.
  • You need an audit trail. Regulated or business-critical environments where you must prove what ran, when, and with what input.
  • You want to remove orchestration from Lambda. Lambda functions that call other Lambda functions are a sign that the orchestration belongs in Step Functions.

When not to use it

  • Trivial one- or two-step logic. If you just call one Lambda function in response to an event, EventBridge or direct Lambda invocation is simpler and cheaper.
  • Pure event routing. If you are reacting to AWS service events and routing them to targets, EventBridge is built exactly for that. No state machine required.
  • Ultra-high-volume simple pipelines. For millions of small, uniform tasks per hour (image resizing, log normalisation), SQS with Lambda triggers is simpler, cheaper, and easier to scale.
  • Long compute jobs with no workflow branching. If you need to run a CPU-heavy job to completion, AWS Batch is a better fit than Step Functions wrapping a Lambda.
  • Very low latency requirements across many steps. Step Functions adds orchestration overhead per state transition. For sub-100ms response times across multiple steps, direct Lambda-to-Lambda calls or synchronous Express workflows may be better.

Common use cases

  • Order processing. Validate, charge payment, reserve inventory, send confirmation, trigger fulfilment. Each step can fail independently. The workflow handles retries and routes failures to compensating transactions.
  • Approval workflows. A workflow pauses using a Wait state with a callback token. When a human approves or rejects in a UI, the token is returned and the workflow continues to the appropriate branch.
  • ETL and data pipelines. Extract data from a source, transform it via Lambda or Glue, validate the result, and load it to a destination. Step Functions orchestrates the steps and retries on failures. See also: designing data pipelines.
  • Security and ops automation. Detect a threat, quarantine the affected resource, notify the team, wait for acknowledgment, and remediate. The workflow ensures all steps run in order and are logged for audit.
  • Microservice orchestration. For services that must be called in a specific sequence with result passing, error handling, and compensating calls on failure, Step Functions provides a durable coordination layer that is observable without reading multiple log streams.
  • ML inference pipelines. Pre-process input, invoke a SageMaker endpoint, post-process the result, and store the output, all coordinated as a single durable execution with retry on transient endpoint failures.

Example workflow: order processing

This state machine handles an order through validation, payment, inventory check, and fulfilment. It demonstrates Task states with retry and catch, a Choice state for conditional branching, and a Parallel state for running fulfilment steps concurrently.

Step Functions is a good fit here because each step can fail independently with different recovery paths. A payment decline is handled differently from a validation error. You also need a complete audit trail of what happened to each order.

{
  "Comment": "Order processing workflow",
  "StartAt": "ValidateOrder",
  "States": {
    "ValidateOrder": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:validate-order",
      "Next": "ProcessPayment",
      "Retry": [
        {
          "ErrorEquals": ["Lambda.ServiceException", "Lambda.TooManyRequestsException"],
          "IntervalSeconds": 2,
          "MaxAttempts": 3,
          "BackoffRate": 2
        }
      ],
      "Catch": [
        {
          "ErrorEquals": ["ValidationError"],
          "Next": "OrderFailed"
        }
      ]
    },
    "ProcessPayment": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:process-payment",
      "Next": "CheckInventory",
      "Catch": [
        {
          "ErrorEquals": ["PaymentDeclined"],
          "Next": "OrderFailed"
        }
      ]
    },
    "CheckInventory": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.inventoryAvailable",
          "BooleanEquals": true,
          "Next": "FulfillOrder"
        }
      ],
      "Default": "OrderFailed"
    },
    "FulfillOrder": {
      "Type": "Parallel",
      "Branches": [
        {
          "StartAt": "ReserveInventory",
          "States": {
            "ReserveInventory": {
              "Type": "Task",
              "Resource": "arn:aws:lambda:us-east-1:123456789012:function:reserve-inventory",
              "End": true
            }
          }
        },
        {
          "StartAt": "SendConfirmationEmail",
          "States": {
            "SendConfirmationEmail": {
              "Type": "Task",
              "Resource": "arn:aws:lambda:us-east-1:123456789012:function:send-email",
              "End": true
            }
          }
        }
      ],
      "Next": "OrderComplete"
    },
    "OrderComplete": {
      "Type": "Succeed"
    },
    "OrderFailed": {
      "Type": "Fail",
      "Error": "OrderFailed",
      "Cause": "Order could not be processed"
    }
  }
}

What this workflow does:

  1. Validates the order. Retries on transient Lambda errors with exponential backoff. Routes validation failures to OrderFailed.
  2. Processes payment. Routes payment declines to OrderFailed without retrying (you do not want to retry a declined card).
  3. Checks if inventory is available using a Choice state that reads $.inventoryAvailable from the previous step’s output.
  4. If inventory is available, runs inventory reservation and confirmation email in parallel. Both must succeed to continue.
  5. Ends at OrderComplete or OrderFailed, each with a full audit trail of every step.

Creating and running a state machine

# Create the state machine
aws stepfunctions create-state-machine \
  --name order-processing \
  --definition file://order-processing.json \
  --role-arn arn:aws:iam::123456789012:role/StepFunctionsRole \
  --type STANDARD

# Start an execution
aws stepfunctions start-execution \
  --state-machine-arn arn:aws:states:us-east-1:123456789012:stateMachine:order-processing \
  --name "order-12345" \
  --input '{"orderId": "12345", "amount": 99.99, "items": ["item-a", "item-b"]}'

# Check execution status
aws stepfunctions describe-execution \
  --execution-arn arn:aws:states:us-east-1:123456789012:execution:order-processing:order-12345

The Step Functions execution role needs permission to invoke each Lambda function in the workflow. For direct service integrations (calling DynamoDB, S3, or other services without Lambda), the role also needs the relevant service permissions. See IAM roles explained for how execution roles work.

Standard vs Express workflows

Step Functions offers two workflow types. The choice affects execution semantics, maximum duration, observability, and pricing.

FeatureStandardExpress
Maximum durationUp to 1 yearUp to 5 minutes
Execution semanticsExactly-onceAt-least-once (async) / At-most-once (sync)
Execution historyFull history in console and API (90 days)CloudWatch Logs only
Pricing modelPer state transitionPer execution count and duration
Best forLong-running, critical, or auditable workflowsHigh-volume, short-lived workflows

Standard workflows guarantee exactly-once execution. Each state transition happens once, even if there are infrastructure-level retries. The full execution history is visible in the AWS console and queryable via the API. Standard workflows are the right choice for business processes like order fulfilment, approval workflows, or any workflow where idempotency and auditability matter. They can run for up to a year, making them suitable for workflows that pause for extended periods.

Express workflows come in two variants. Asynchronous Express workflows fire-and-forget with at-least-once semantics: the same step may execute more than once, so your Lambda functions need to handle duplicate executions gracefully. Synchronous Express workflows wait for the execution to complete and return the result directly, with at-most-once semantics. Express workflows are priced by duration rather than by state transition, making them much cheaper for high-volume, short-lived flows.

Watch out

Asynchronous Express workflows have at-least-once execution semantics. The same step can execute more than once under certain conditions. If your Lambda function writes to a database, sends an email, or charges a payment, duplicate executions will produce duplicate side effects. Design your Lambda functions to be idempotent before using async Express workflows.

When in doubt, start with Standard. Move to Express only when you have measured the cost impact at your target volume and confirmed your tasks handle duplicates correctly.

AWS Step Functions vs SQS vs EventBridge

These three services are often compared because they all connect AWS services together, but they solve different problems.

Step FunctionsSQSEventBridge
Primary roleWorkflow orchestrationMessage queuingEvent routing
Controls what happens nextYes, explicit state transitionsNo, consumers decideNo, rules route to targets
Tracks execution stateYesNoNo
Handles retriesBuilt-in per stateVia visibility timeout and DLQVia retry policy and DLQ on the rule
Best forMulti-step business processes with branchingLoad levelling, worker pools, decouplingReacting to AWS service events, fan-out routing

Step Functions is for orchestration: it controls the sequence, the branching, and the error routing. It knows the state of every execution.

SQS is for queuing: it buffers messages between producers and consumers, handles load levelling, and ensures messages are not lost if a consumer is temporarily unavailable. It does not know or care about workflow state. For more, see the Amazon SNS overview which covers both SNS and SQS and when to use each.

EventBridge is for event routing: it receives events from AWS services and routes matching events to targets based on pattern matching. It is not designed to track multi-step workflow state. See Amazon EventBridge overview for the full picture.

These services are often combined. A common pattern: an EventBridge rule detects an event (an S3 upload, a CodePipeline state change) and starts a Step Functions execution, which orchestrates the multi-step processing workflow, with SQS buffers feeding Lambda tasks at high-volume steps.

Quick decision guide:

  • Use Step Functions when you have a multi-step workflow with conditional branching, error handling, and auditing needs.
  • Use SQS when you need to decouple producers and consumers, or buffer high-volume work for downstream processing at its own pace.
  • Use EventBridge when you want to react to AWS service events or route custom events between services without managing workflow state.

Common mistakes

  1. Putting orchestration logic inside Lambda functions. If a Lambda function calls other Lambda functions directly and manages the sequence, you have hidden orchestration with no visibility, no durability, and no reliable error handling. Move the orchestration to Step Functions where the workflow is explicit, observable, and replayable.
  2. Missing retry and catch configuration. Lambda functions can fail transiently due to throttling, cold starts, or network issues. Always add a Retry block for Lambda.ServiceException and Lambda.TooManyRequestsException with exponential backoff. Without it, a single transient failure terminates the execution permanently.
  3. Choosing the wrong workflow type. Standard workflows charge per state transition. For millions of short two-step executions per hour, Express workflows are significantly cheaper. Run the numbers before defaulting to Standard for high-volume, short-lived workflows.
  4. Not configuring CloudWatch Logs for Express workflows. Express workflows do not write execution history to the Step Functions console. Without explicit CloudWatch Logs configuration on the state machine, there is nothing to look at when an Express execution fails.
  5. Passing large payloads between states. The state payload has a size limit. Passing large data (file contents, full database query results) through the state will fail. Store large data in S3 or DynamoDB and pass only the reference key between states.
  6. Not thinking about idempotency for Express workflows. Asynchronous Express workflows have at-least-once semantics. A step may execute more than once under certain conditions. If the Lambda function writes to a database or sends an email, a duplicate execution can produce duplicate side effects. Design functions to be idempotent where this matters.

Best practices

  • Keep Lambda functions small and single-purpose. Each Task state should call a Lambda function that does one thing. The orchestration logic belongs in the state machine definition, not in the function body.
  • Use direct SDK integrations where possible. For simple AWS API calls (writing to DynamoDB, publishing to SNS), use direct integrations rather than wrapping them in Lambda. Fewer Lambda functions means lower cost and less to maintain.
  • Enable distributed tracing. Step Functions integrates with AWS X-Ray. Enable tracing on the state machine and on the Lambda functions it invokes to get end-to-end visibility across the workflow from a single trace.
  • Use meaningful execution names. If you start an execution with the same name twice, Step Functions returns an error for the second attempt rather than starting a duplicate. Use a natural unique identifier like an order ID as the execution name to get free idempotency at the execution level.
  • Log execution outcomes to CloudWatch. Configure CloudWatch Logs on your state machines to capture execution-level events at ERROR or ALL level. This makes it straightforward to build alerts on workflow failure rates.
  • Test with small inputs first. The Step Functions console lets you execute a state machine with a custom input and watch the execution graph update in real time. Use this before connecting the state machine to production event sources.

Frequently asked questions

What is AWS Step Functions used for?

Step Functions is used to coordinate multi-step workflows across Lambda functions and other AWS services. Common uses include order processing, approval workflows, ETL data pipelines, security automation, and microservice orchestration. It handles retries, branching, waiting states, and error handling, removing that logic from your application code.

When should I use Step Functions instead of Lambda?

Use Step Functions when your logic involves multiple sequential or parallel steps, branching, long waits, or error handling across services. If you find yourself writing Lambda functions that call other Lambda functions, that is a signal to move the orchestration to Step Functions, where the workflow is explicit, durable, and observable.

What is the difference between Standard and Express workflows?

Standard workflows run for up to 1 year, guarantee exactly-once execution, and log every step in the console. Express workflows run for up to 5 minutes and are priced by duration, which makes them better for high-volume, short-lived workflows. Synchronous Express workflows return a result directly. Asynchronous Express workflows fire-and-forget with at-least-once semantics.

Is Step Functions better than EventBridge or SQS?

They solve different problems. Step Functions orchestrates multi-step workflows: it controls what happens next and tracks execution state. EventBridge routes events from one service to another. SQS buffers messages between services. For a complex business process with branching and retries, Step Functions is the right tool. For pure event routing or load levelling, use EventBridge or SQS.

Can Step Functions call services other than Lambda?

Yes. Step Functions has direct SDK integrations with over 200 AWS services, including DynamoDB, S3, SNS, SQS, ECS, Glue, and SageMaker. Many integrations can call AWS APIs directly from a Task state without needing an intermediate Lambda function.

Last verified: 1 April 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.