Step Functions Standard vs. Express Workflows: Choosing Between Durability and Throughput
Standard Step Functions workflows trade speed for durability and exactly-once execution; Express workflows trade durability for low latency and lower cost. Learn how to decide, with a CLI example and verification steps.
10 Sept 2026, 20:01 UTC

The orchestration fork in the road
Your Lambda functions are timing out because they are waiting on three downstream APIs, retry logic is scattered across try/catch blocks, and nobody can tell you exactly where a failed job stopped. You need orchestration, but the moment you open the Step Functions console you face a fork in the road: Standard or Express?
Standard workflows are durable, exactly-once state machines built for business-critical processes. Express workflows are stateless, high-speed pipelines built for short, high-frequency event processing. Choosing wrong means either paying for durability you do not need or losing state you cannot afford to lose.
Same JSON, different execution guarantees
Both workflow types use the same JSON-based Amazon States Language, so the state machine definition looks identical. What changes is the runtime promise behind it.
Standard persists every state transition to an internal history store. That gives you exactly-once execution, full retry controls, and the ability to pause for hours or days using .waitForTaskToken patterns. The trade-off is higher latency per step and a per-state-transition billing model.
Express runs statelessly in memory. It starts instantly, costs less per execution at high volume, and is billed by request count plus duration. However, it guarantees at-least-once delivery, not exactly-once, and it caps execution at five minutes. It also supports a narrower set of service integrations, so patterns that wait for external callbacks are unavailable.
Worked example: deploy both and inspect them
The fastest way to internalize the difference is to create the same minimal workflow as both types and compare what you can query afterward.
Save this definition locally as workflow.json. It is deliberately trivial—a single Pass state that returns a fixed result:
{
"Comment": "Minimal test workflow",
"StartAt": "ProcessEvent",
"States": {
"ProcessEvent": {
"Type": "Pass",
"Result": { "status": "ok" },
"End": true
}
}
}
Run the following commands from a terminal with the AWS CLI configured (CloudShell works too). You need states:CreateStateMachine and iam:PassRole for the execution role.
Create the Standard workflow
aws stepfunctions create-state-machine \
--name event-processor-standard \
--type STANDARD \
--definition file://workflow.json \
--role-arn arn:aws:iam::123456789012:role/service-role/StepFunctionsEventProcessorRole \
--region us-east-1
Create the Express workflow
aws stepfunctions create-state-machine \
--name event-processor-express \
--type EXPRESS \
--definition file://workflow.json \
--role-arn arn:aws:iam::123456789012:role/service-role/StepFunctionsEventProcessorRole \
--region us-east-1
Replace 123456789012 with your account ID and adjust the region if needed. The role must trust states.amazonaws.com; if it does not, creation fails with an access error.
Verify the type
Confirm what you built:
aws stepfunctions describe-state-machine \
--state-machine-arn arn:aws:states:us-east-1:123456789012:stateMachine:event-processor-standard
Expected check: the response includes "type": "STANDARD". Run the same command against the Express ARN and you should see "type": "EXPRESS".
Start an execution and observe the difference
aws stepfunctions start-execution \
--state-machine-arn arn:aws:states:us-east-1:123456789012:stateMachine:event-processor-standard \
--input '{"source":"cli-test"}'
For the Standard run, capture the returned executionArn and query its history:
aws stepfunctions get-execution-history \
--execution-arn arn:aws:states:us-east-1:123456789012:execution:event-processor-standard:abc123
You will see each state transition recorded. For the Express workflow, get-execution-history does not return the same step-by-step record. Instead, enable CloudWatch Logs in the state machine settings and inspect the execution logs there. That API gap is the clearest signal of the durability difference.
The trade-off that usually decides it
Express workflows feel magical for high-frequency event processing—ingesting clickstreams, transforming IoT payloads, or fanning out S3 events—because they start without cold-start delay and cost pennies per million requests. But the five-minute ceiling and the lack of .waitForTaskToken mean you cannot pause for a human approval or a long-running batch job.
Standard workflows absorb that complexity. They can run for up to a year, retry failed steps with exponential backoff, and let you resume from the exact point of failure. The cost is latency: each state transition incurs overhead, and the execution history store adds write latency that Express simply does not pay. If your workflow uses callback patterns, the execution role for Standard also needs permissions such as states:SendTaskSuccess and states:ReceiveTask; Express only needs states:StartExecution because it does not support those integrations.
| Dimension | Standard | Express |
|---|---|---|
| Execution semantics | Exactly-once | At-least-once |
| Maximum duration | Up to 1 year | 5 minutes |
| Latency profile | Higher per-step overhead | Instant start, low overhead |
| History / debugging | Queryable via API | CloudWatch Logs only |
| Callback patterns | Supported | Not supported |
How to decide and verify
Ask three questions before you commit:
- Does the workflow need to run longer than five minutes or wait for an external callback? If yes, Standard is your only option.
- Can your downstream system tolerate duplicate processing? Express is at-least-once, so idempotency keys are mandatory.
- Do you need to query execution history through the Step Functions API? If yes, choose Standard; Express logs to CloudWatch instead.
Because both types share the same Amazon States Language, migrating later is mostly a matter of changing the --type flag and updating the state machine ARN in your callers. Abstract that ARN behind an environment variable or parameter store entry so the switch does not ripple through your codebase.
Before you scale either pattern, run a load test: start 100 executions against both state machines, measure end-to-end latency in CloudWatch, and compare the cost line items on your bill. If Express handles your volume in under a second and your workflow has no wait states, it is likely the cheaper, faster path. If you need to pause for approval or guarantee that a payment is processed exactly once, Standard is worth the overhead.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.