Migrate from AWS Step Functions to Temporal: what the move involves
Moving from AWS Step Functions to Temporal is a code rewrite plus a staged cutover, not a file import. Amazon States Language definitions describe states in JSON, while Temporal expresses the same logic as workflow and activity code in a supported SDK language, so each state machine has to be re-implemented, tested and then switched over one workflow family at a time. Teams usually arrive here because of a renewal, a data residency rule or a wish to run orchestration inside their own network, and the first decision is whether the work justifies the rewrite at all. Platform engineers normally lead the effort, with application owners confirming the business behavior of each workflow, retry expectations and downstream side effects. The short answer on effort and risk depends on how many state machines exist, how many call AWS services directly through service integrations, and how many run long enough to need careful versioning. Build an inventory first and rank workflows by risk before estimating anything.
Temporal's server is licensed under the MIT license, so the orchestration engine itself carries no license fee, and you can run it in your own cloud accounts or data center. Temporal Cloud is a separate, managed option sold by Temporal Technologies with its own pricing, so the choice between running the server and buying the managed service is an operations and cost decision, not a license decision. Ask for a written scope that names the workflows in each wave, the persistence and visibility stores you will run, who owns the on-call rotation, and what must be retained from Step Functions execution history before it expires. Keep the old state machines running until each new workflow has passed parallel testing with real inputs, and plan the cutover so that in-flight executions finish on the system where they started. Confirm the current server and SDK versions and the upgrade path with Temporal before you commit to a timeline.
Which Step Functions capabilities map to Temporal, and what needs rework
This table maps each Step Functions capability to its closest Temporal equivalent and labels it as a clean translation, work that needs rework, or a gap. Read the rework rows as the places where engineers will rewrite logic, not just move a JSON file. Amazon States Language has no direct import path into Temporal, so every definition becomes code.
| Step Functions capability | Temporal equivalent | Status and what to plan |
|---|---|---|
| Task state (Lambda or service call) | Activity called from a workflow function | Needs rework: each AWS service integration must be rebuilt as an activity with its own SDK client, credentials and retry settings. |
| Choice state | Native if, switch or conditional logic in workflow code | Clean: branching logic translates directly, but comparison operators and JSONPath expressions must be rewritten in the host language. |
| Wait state | Durable timer (sleep or timer call in the workflow) | Clean: timers persist across worker restarts, but long waits still count toward history and retention limits. |
| Parallel and Map states | Concurrent activity futures, child workflows or fan-out with bounded concurrency | Needs rework: concurrency limits, result ordering and error aggregation must be coded explicitly. |
| Retry and Catch | Activity and workflow retry policies with try and catch blocks | Needs rework: map each ErrorEquals list to a retry policy or an exception type, then test non-retryable errors. |
| Timeouts (TimeoutSeconds, HeartbeatSeconds) | Start-to-close, schedule-to-close and heartbeat timeouts on activities | Needs rework: choose which timeout type each activity needs, because Temporal separates them more finely. |
| Callback task tokens (.waitForTaskToken) | Signals and workflow waits on a condition | Needs rework: external systems must send a signal to the workflow ID instead of returning a token, so the sender needs the workflow ID. |
| Execution history and visibility | Workflow event history and visibility store | Gap in portability: Step Functions history cannot be imported. Plan to archive exports and confirm the retention you need in your Temporal persistence and visibility setup. |
| Versioning of state machine definitions | Workflow versioning with patching or worker build IDs | Needs rework: in-flight executions must keep running on the code that started them, so plan version markers before changing workflow code. |
Which definitions, histories and integrations to export and rebuild
A migration from Step Functions to Temporal succeeds or fails on what you capture before the first line of workflow code is written. The items below form one inventory: the definitions, the execution history, the IAM roles and the service integrations that each state machine depends on. Every card feeds the rebuild plan, so treat the inventory as the source of truth rather than the console.
Export state machine definitions
Retrieve each Amazon States Language definition with the DescribeStateMachine API call, for every state machine in every account and Region in scope. Store the JSON in version control with the account ID, Region and ARN recorded alongside it. Each definition is the blueprint for the Temporal workflow, so each Task, Choice, Wait, Parallel and Map state must be mapped to code. Confirm in the AWS Step Functions documentation which fields the export returns for your state machine type.
Save execution history early
Execution history is not a migration artifact you can rebuild later. Export the history of executions you still need for audit or support before it ages out of the console. Record which executions were running at cutover, since those are the ones that need a drain plan or a manual decision. Confirm the retention window that applies to your account and whether your compliance team requires a longer archive.
Decrypt KMS-encrypted definitions
When a state machine definition or its logging configuration uses a customer managed KMS key, the reader's role needs permission to call decrypt on that key before the definition can be read in plain form. Missing key permissions often surface only during a migration, not during normal operation. Document which keys protect which artifacts, who can use them, and where the decrypted copies are stored. Keep decrypted definitions in the same controlled repository as the rest of the inventory.
Capture IAM roles and permissions
Each state machine runs under an execution role that grants access to downstream services such as Lambda, DynamoDB, SQS or ECS. In Temporal, those permissions move to the worker processes and their service accounts, so the mapping must be explicit. List every role, its attached policies and the resources it reaches. Then decide which credentials each activity worker will hold, and whether they should be short-lived or scoped per workflow type.
Map service integrations to activities
Optimized and SDK service integrations in Step Functions call AWS APIs directly from the state. In Temporal, each of those calls becomes an activity that a worker executes, with its own retry policy and timeout. Record each integration pattern used, including any wait-for-callback calls, and the AWS SDK operation behind it. Activities that call AWS directly will still need network paths and credentials that the self-hosted cluster can reach.
Keep the inventory as the rebuild source
Use the inventory as the single input for sequencing, testing and sign-off. Each row should link a definition, its history sample, its roles, its integrations and an owner. Mark any state machine that depends on a callback token or an external system that cannot move, because those need a signal design. Keep the inventory under change control until cutover, and confirm each AWS-specific detail against current AWS documentation for your own account.
Migration sequence from inventory to decommission
This sequence moves Step Functions workloads to Temporal in controlled stages, so each workflow is proven on Temporal before its traffic moves and Step Functions is retired only after nothing depends on it. Each step ends with a named artifact that the next step relies on.
Build the inventory of definitions and integrations
Export every state machine's Amazon States Language definition, the IAM role attached to it, and the list of service integrations it calls, such as Lambda, DynamoDB, SQS or other AWS APIs. Record which workflows are started by EventBridge, API Gateway, schedules or other state machines, and note the execution history retention you need to keep. The output is a migration inventory with one row per state machine, its owners, its callers, its external dependencies and a risk rating. The step is done when the platform team and the workflow owners have signed off on that inventory.
Choose and stand up the Temporal environment
Decide the deployment method (Docker Compose, Go binaries, or Helm charts on Kubernetes) and the persistence database that your standards support, from the versions Temporal has tested. Confirm the visibility store you will use, and place the services on hosts that are not reachable from the public internet. Configure an Authorizer and a ClaimMapper before any workflow runs, because a self-hosted install without an Authorizer accepts every API request. The output is a hardened non-production cluster and a short architecture note. The step is done when a test worker can start and complete a sample workflow through the frontend.
Pilot one low-risk state machine
Select one workflow from the inventory that has few integrations, no long-running waits and a clear business owner. Rewrite its Task, Choice, Wait and error-handling states as a Temporal workflow with activities, then run it in a staging namespace against the same downstream systems. Compare inputs, outputs and failure behavior with the Step Functions execution history for the same test cases. The output is a pilot test report listing matched behaviors, known differences and the decisions made about retries and timeouts. The step is done when the owner accepts the report.
Translate and test the remaining workflows
Translate the rest of the inventory in batches, grouped by shared integrations and risk. Map Parallel and Map states to fan-out logic with bounded concurrency, replace task token callbacks with Temporal signals, and move any Wait states longer than a few seconds to durable timers. Put each workflow under version control and add a test suite that replays representative histories and covers failure paths. The output is a tested code repository and a translation log that links each Amazon States Language state to its Temporal construct. The step is done when every workflow in the batch passes its tests and has an owner.
Run both systems in parallel
Route new executions to Temporal for each workflow while the Step Functions version remains deployed and able to receive work. Compare outcomes, latency, error rates and downstream side effects for the same business events, and watch for duplicate actions caused by two systems handling one event. Use idempotency keys on every side-effecting activity during this period. The output is a parallel-run dashboard and a log of discrepancies with a disposition for each. The step is done when discrepancies are resolved and the owners agree that Temporal behaves as expected.
Cut over each workflow with a runbook
For each workflow, write a cutover runbook that names the trigger source to repoint, the point after which new events go only to Temporal, the procedure for draining or stopping in-flight Step Functions executions, and the rollback path. Let Step Functions finish executions already in progress before retiring its trigger, and confirm Temporal's visibility shows the expected counts. The output is a signed cutover runbook and a cutover record for each workflow. The step is done when the workflow has run on Temporal for its agreed observation period with no open incidents.
Decommission Step Functions and archive evidence
After all workflows have cut over, disable the remaining triggers, delete the state machines and their IAM roles, and retain the exported definitions, execution history and runbooks as records in storage you control. Remove any KMS grants and CloudWatch log subscriptions that no longer serve a purpose, and confirm no other service still calls the state machines. The output is a decommission record that lists each deleted resource and where its archive is kept. The step is done when a second review of the inventory finds no active dependency on Step Functions.
How callback patterns become Temporal signals
In Step Functions, a task that waits for an outside system usually uses the callback pattern: the state passes a task token to a downstream service, which later calls SendTaskSuccess or SendTaskFailure with that token. In Temporal, the equivalent is a workflow that blocks on a signal while an activity or an external caller does the outside work. The migration decision is where the token's job goes. Map each token-based state in your inventory to one of two shapes: a signal the workflow waits for, identified by a workflow ID that your system of record already stores, or an activity that calls the external system and returns only when it finishes. Record which external system sends the completion, how it identifies the waiting run, and what happens if it never answers. Illustrative example (hypothetical): an approval state that waits for a human decision in an internal ticketing tool would become a workflow that waits on an approval signal, with the ticketing webhook sending that signal using the workflow ID stored with the ticket.
Wait states translate to durable timers in workflow code, so a 24-hour wait survives worker restarts and deployments without a separate scheduler. Confirm with your own tests that timer behavior matches the Step Functions timeout settings you rely on, especially where a Step Functions state has a TimeoutSeconds or HeartbeatSeconds value. Parallel and Map states become concurrent activity calls issued from workflow code. The risk here is unbounded fan-out: a Map over a large array can flood downstream services and the Temporal history. Set an explicit concurrency limit in the workflow, cap the size of each batch, and check that the Temporal server and persistence database can absorb the event volume at your peak. Test these limits against your own load profile before cutover, since the right bound depends on your activities and downstream capacity, not on a general rule.
Signals also need a versioning plan. A signal sent to a workflow run that has since changed shape can fail or be ignored, so define signal names and payload schemas as a contract, and keep older workers able to handle signals for runs already in flight. Plan to drain or migrate those in-flight executions during the side-by-side period rather than assuming they finish under the new code. Review the Temporal documentation on workflow and signal behavior for your server version before you finalize the design.
Choosing a Temporal deployment and persistence path for the migration
Self-hosted Temporal can be deployed in four ways, and the right one depends on how much platform tooling your team already runs. Docker Compose suits proofs of concept and small test environments. Go binaries give you direct control over each service on hosts you manage. Helm charts run the Temporal Server services in individual Kubernetes pods and fit teams that already operate clusters. A custom Go build imports the server package into your own binary, which suits teams that need to change server internals, at the cost of owning that build pipeline.
- Docker Compose: Useful for evaluating the migration on a single host, not for a production cutover.
- Go binaries: Each Temporal service runs as a process you supervise, so your team owns service management and restarts.
- Helm charts on Kubernetes: Chart versions below 0.73.1 do not work with server images 1.30 and later, so pin the chart version to match the server image.
- Custom Go build: Importing the server package adds a build and patching responsibility that continues after go-live.
- Network placement: Temporal services should run on hosts that are not reachable from the public internet.
Confirm the chosen deployment method against the current Temporal deployment documentation before you pin versions in your infrastructure code.
Temporal stores workflow state in a persistence database, and the supported engines and versions set the constraints for your platform. PostgreSQL 13 to 16 is the option most platform teams already operate, and it has the widest set of managed offerings. MySQL 5.7 and 8.0.19 or later is also supported. Cassandra 3.11, 4.0 and 5.0.4 or later remains supported for persistence. SQLite is meant only for development and testing, so it should never hold production history.
- PostgreSQL 13 to 16: The tested range for persistence; check your managed service's version against it before provisioning.
- MySQL 5.7 and 8.0.19 or later: Supported as a persistence store, so confirm the exact minor version you plan to run.
- Cassandra 3.11, 4.0 and 5.0.4 or later: Suits teams that already run Cassandra at scale and have the operational skills for it.
- SQLite: Limited to development and testing, not production.
- Backups and restore: Test restoring the persistence database to a separate environment, because workflow history depends on it.
Ask your database team which engine they can back up, monitor and restore within your recovery targets, and confirm the version against the Temporal persistence documentation.
Advanced visibility lets operators search workflow executions by attributes, which matters once you move many state machines and need to find failed or long-running runs. Temporal supports Elasticsearch 7 and 8, and OpenSearch 2 or later from Temporal Server 1.30.1. MySQL 8.0.17 or later, PostgreSQL 12 or later and SQLite are supported for advanced visibility from server 1.20, and Cassandra visibility was removed in 1.24. Temporal's documentation recommends Elasticsearch or OpenSearch for anything beyond a few workflow executions.
- Elasticsearch or OpenSearch: The recommended choice for production volumes, and a separate cluster your team must size, secure and back up.
- PostgreSQL or MySQL visibility: A simpler option with fewer moving parts, which may be enough for low execution counts. Confirm the expected volume with your team before choosing it.
- Cassandra visibility: Not available in current server versions, so it cannot be the visibility store for a new deployment.
- Operational cost: A search cluster adds licensing review, storage, upgrades and on-call scope, so include it in the cost model.
- Index planning: Decide which search attributes your operators need before cutover, because they shape queries later.
Verify the supported visibility version against the Temporal visibility documentation before you commit to a store.
Self-hosted Temporal has no access control by default. If no Authorizer is configured, the server uses the default noopAuthorizer, which allows every API request with no authentication or access control. Any workflow that moves into a shared cluster without an Authorizer is open to every host that can reach the frontend. Treat the security settings as a gate that must pass before any production traffic or cutover.
- Authorizer: Configure an Authorizer plugin so every API call is checked against namespace roles.
- ClaimMapper: Map JWT or certificate claims from your identity provider to namespace roles.
- mTLS: Enable mutual TLS with separate settings for internode and frontend traffic.
- OIDC for the Web UI: Turn on single sign-on for the Web UI so operators authenticate through your identity provider.
- Payload encryption: Use custom codecs and a codec server if workflow payloads contain regulated data.
Before cutover, test each setting in a staging cluster, and have your security team confirm the configuration against your own control requirements.
What drives migration cost and duration
This table lists the factors that most change the effort of moving Step Functions state machines to Temporal, with why each matters and how to keep it under control. Read it as a scoping checklist: the more a driver applies to your estate, the more discovery, code translation and parallel running your written scope should cover.
| Driver | Why it changes cost or effort | How to keep it down |
|---|---|---|
| Number of state machines | Each state machine becomes a Temporal workflow definition with its own tests, versioning and cutover step, so effort scales with the inventory count. | Export every definition first, group near-identical machines into shared workflow libraries, and retire unused machines before translating. |
| Depth of AWS service integrations | Task states that call Lambda, SQS, DynamoDB or other services become activities that need their own SDK clients, IAM-equivalent credentials and error handling. | Map each integration to a single activity pattern, reuse clients across workflows, and confirm which AWS calls can move to your own services. |
| Callback and task token patterns | Waiting for an external callback must be rebuilt as Temporal signals, which changes how external systems send events and how timeouts are handled. | Inventory every callback and token consumer early, agree the signal contract with the owning teams, and test timeouts explicitly. |
| Length of long-running executions | Executions that wait days or months need careful handling of history size, timers and the retention period set for your Temporal namespaces. | Measure the longest current executions, plan for continue-as-new where appropriate, and confirm retention settings with your Temporal design. |
| Need for in-flight execution continuity | Running executions cannot simply switch engines, so you must decide whether to drain, restart or finish them on Step Functions during cutover. | Set a cutover rule per workflow type, drain short executions, and keep Step Functions running until long executions complete. |
| Number of environments | Each environment needs its own Temporal deployment, persistence database, visibility store and configuration, which multiplies infrastructure and testing work. | Standardize Helm or Compose configuration across environments and automate namespace creation so each environment follows the same pattern. |
| Team Temporal experience | Temporal workflows are code with determinism rules, so teams new to it need training and review time before production work starts. | Pilot one representative workflow, pair engineers with experienced reviewers, and budget training time in the written scope. |
| Visibility and security setup | Advanced visibility requires a supported Elasticsearch, OpenSearch or SQL store, and an open server needs an Authorizer, mTLS and SSO configured before use. | Pick the visibility store from the supported list, restrict network access to internal networks, and configure the ClaimMapper and Authorizer before any production namespace is opened. |
| Temporal Cloud as a comparison point | Temporal Cloud pay-as-you-go pricing starts at 50 US dollars per million actions, with a 99.9% SLA or 99.99% with high availability, per Temporal's pricing page. Self-hosting removes that per-action fee but adds the operations work listed above. | Ask for a total cost comparison that includes servers, persistence, visibility, engineering time and on-call, and confirm current figures on Temporal's pricing page. |
What usually goes wrong and how to prevent it
Most failed Temporal migrations trace back to a handful of decisions made early: how the cluster is exposed, how it is secured, how it is upgraded and how workflow code evolves. The cards below pair each risk with a prevention step you can check before cutover, and they cover the data and integration work that Step Functions hid from your team.
Services exposed to the internet
Temporal's self-hosted deployment guidance says the services should run on hosts that are not reachable from the public internet, with network access limited to trusted internal networks. Teams moving from a managed AWS service often assume the endpoint is protected by default and expose the frontend for convenience. Prevention: place the frontend, history and matching services on private subnets, restrict ingress to known worker and client networks, and verify from outside the network that no Temporal port answers.
Running without an Authorizer
If no Authorizer is configured, self-hosted Temporal falls back to the default noopAuthorizer, which allows every API request with no authentication or access control. Anyone who can reach the frontend can start, signal or terminate workflows. Prevention: configure a ClaimMapper and an Authorizer before any production namespace receives traffic, enable mTLS between services and clients, and test that an unauthenticated call is rejected.
Mismatched Helm chart and server versions
Helm chart versions below 0.73.1 do not work with server images 1.30 and later. Pinning a chart from an old example and pulling the latest server image can produce a deployment that fails at startup or behaves unpredictably. Prevention: pin the chart and server image versions together in source control, record both in the change record, and run a staging deployment with the exact pair before production.
Skipping the minor-by-minor upgrade path
Backward compatibility is guaranteed only between two successive minor versions, so jumping several minor releases at once is unsupported. Schema upgrades must also run before server upgrades when the release notes call for them. Prevention: move to the latest patch of your current minor first, then step one minor version at a time, reading the release notes at each step and applying schema changes in the order the upgrade guide specifies.
Non-deterministic changes to workflow code
Temporal replays workflow history to recover state, so changing the order of activity calls, timers or random decisions in workflow code can break in-flight executions that were started on the old logic. Step Functions definitions were versioned as whole state machines, which hides this risk. Prevention: use Temporal's workflow versioning or patching for logic changes, keep workflow code free of direct clock, random and I/O calls, and replay representative histories in tests before each deployment.
Losing execution history before export
Step Functions retains execution history for a limited window, and a migration inventory that only copies definitions loses the record of runs that are still in progress or need audit evidence. Prevention: export state machine definitions, IAM roles and service integrations, and capture execution history for any run that matters before the window closes. Store the export in a location with the same access controls as the original data.
Underestimating AWS integration rebuilds
Step Functions calls Lambda, SQS, DynamoDB and other services directly through service integrations and optimized callbacks. In Temporal, each of these becomes an activity with its own retry policy, credentials, timeouts and error handling, and task-token callbacks become signals. Prevention: list every service integration in the inventory, assign each an owner, write activities with explicit timeouts, and run both systems side by side with duplicate-action checks until cutover is verified.
How the migration differs by starting point
A small set of state machines owned by one team is the simplest starting point. The main work is translating definitions into code and making sure one team can operate the cluster and its on-call rotation. Because the blast radius is limited, the team can often run a single Temporal environment for development and staging before promoting the first production workflow.
- Inventory first: List every state machine, its triggers, and its service integrations, then decide which ones are worth moving at all.
- Pick one pilot: Choose a workflow with clear inputs and outputs and a modest number of Task states to prove the translation pattern.
- Keep the cluster small at first: A single-team estate usually needs one namespace and one persistence backend, so the operational surface stays manageable.
- Run the pilot beside the original: Route a fraction of new executions to Temporal while Step Functions keeps the rest, then retire the old state machine once results match.
- Document the runbook early: With one team, knowledge sits in few heads, so write down deployment, upgrade and incident steps before the second workflow moves.
Before starting, confirm with the team who will carry the pager for the Temporal cluster and whether that matches the time they can spare.
A large estate spread across many AWS accounts, with heavy Express usage, changes the sequence more than the translation. High-volume, short-running Express workflows usually need a different sizing and visibility plan from long-running Standard workflows, and ownership is split across teams. The migration is better planned as waves grouped by business domain than as a single cutover.
- Group by domain and dependency: Move workflows that call the same downstream services together so shared activities and retry policies are built once.
- Size for Express volume: High-frequency short workflows put load on persistence and visibility, so load testing against realistic history growth comes before any wave.
- Standardize namespaces and access: Agree on a namespace model and role mapping across teams before the second wave, so each team does not invent its own.
- Plan visibility early: Choose the advanced visibility store before volume grows, because changing it later means reindexing history.
- Sequence the Express workflows last: Teams often gain confidence on Standard workflows first, then tackle the high-volume paths.
Check with the platform owners how many accounts feed the estate, how many executions per day each domain produces, and which teams hold deployment rights to each account.
In a regulated environment, the first question is where workflow payloads and execution history may live. Temporal records inputs, outputs and event history in its persistence store, so the cluster, database and visibility store all need to sit inside the boundary the regulator or internal policy defines. Security controls and evidence collection become part of the migration scope, not an afterthought.
- Keep the cluster inside your network: Temporal services should run on hosts that are not reachable from the public internet, with access limited to trusted internal networks.
- Lock down the API surface early: Without a configured Authorizer, the default allows every API request, so authorization, mTLS and a ClaimMapper should be in place before any production namespace exists.
- Encrypt payloads: Plan custom payload codecs and a codec server where workflow data is sensitive, and test that operators can still debug executions.
- Plan the control evidence: Map which controls the program needs and collect configuration and access records during the parallel run. Independent auditors, not DeployOpen, decide whether they are sufficient.
- Compare with a managed option on paper: Temporal Cloud is a separate, vendor-hosted service and may not satisfy the same residency rule, so confirm that with compliance before deciding.
Confirm with the compliance lead which data classes the workflows touch and whether any regulator must approve the hosting location.
A team that already operates Kubernetes can deploy Temporal with the Helm chart, running server services as separate pods, and reuse existing ingress, secrets and monitoring. The main constraint is version pairing: chart versions below 0.73.1 do not work with server images 1.30 and later, so the chart and server image must be selected together.
- Pin chart and image together: Choose a chart version that supports the server image you plan to run, and record both in version control.
- Reuse platform services: Use existing secrets management, certificate issuance for mTLS and metrics collection rather than building parallel tooling.
- Separate the persistence database: Run the persistence store as a managed or dedicated database that the cluster connects to, and size it independently of the Kubernetes nodes.
- Automate upgrades with care: Upgrade one minor version at a time, moving to the latest patch of the current minor first, and run schema upgrades before server upgrades when release notes require it.
- Limit network exposure: Use network policies so only approved workers and clients reach the frontend service.
Confirm the target Kubernetes version and whether your cluster policy allows the Helm chart and its required permissions.
A team that does not run Kubernetes can still self-host Temporal with Docker Compose for smaller environments or Go binaries on managed hosts. This path avoids a new platform layer, but the team takes on process supervision, restarts, backups and upgrades that Kubernetes would otherwise handle. The migration plan should name who owns those tasks before the first production cutover.
- Choose the simplest deployment that meets policy: Docker Compose or binaries on hosts can be enough for a limited estate, provided hosts are not publicly reachable.
- Plan process supervision and restarts: Define how services restart after host reboots and how failures alert the on-call team.
- Build backup and restore procedures: Back up the persistence database and test restores, since workflow history depends on it.
- Schedule upgrades deliberately: Without orchestration tooling, each minor upgrade is a manual, reviewed change, one minor version at a time.
- Decide on a future path: If the workflow count grows, record when the team would move to Kubernetes so the decision is not made under pressure.
Ask the operations lead whether the team has existing host automation and who is available to respond to alerts outside business hours.
Questions buyers ask before migrating from Step Functions to Temporal
How much does moving from Step Functions to Temporal cost?
The cost is driven by inventory size and by who runs the platform, not by a single license fee. Temporal's server is MIT licensed, so self-hosting carries no license charge, but you pay for the persistence database, the advanced visibility store (Elasticsearch or OpenSearch is recommended beyond a few workflow executions), compute, engineering time to rewrite definitions as code, and on-call coverage. One-time costs include translating state machines, building activities and testing. Recurring costs include infrastructure, upgrades and monitoring. Ask any services partner for a written quote that lists each component, the number of state machines in scope, and which environments are included. DeployOpen issues quotes only from a written scope.
How long does a Step Functions to Temporal migration take?
The timeline depends on how many state machines you have, how many use service integrations, callbacks and long waits, and how many workflows must run side by side during cutover. Teams with a small set of linear workflows move faster than teams with nested Parallel and Map states and external callback tokens, which need signal-based redesign. Temporal's upgrade guidance also shapes planning: self-hosted servers should move one minor version at a time, and some releases require schema upgrades before server upgrades. Ask for a timeline tied to a fixed scope and a dated list of deliverables, and confirm which environments and cutover windows are assumed.
What does the migration need from our engineering team?
Expect to involve application engineers who own the business logic, platform engineers who run the cluster, and security staff who approve the access model. Application engineers translate Task, Choice, Wait, Parallel and Map states into workflow and activity code and decide how callbacks become signals. Platform engineers manage the persistence database, visibility store, networking and upgrades. Security reviews the authorizer, mTLS and OIDC settings. Your team also needs to confirm which AWS services each state calls, since those integrations must be rebuilt as activities with their own IAM or credential handling.
Can our own team run the migration and operate Temporal without a partner?
Yes, if you have engineers who can write Go, Java, Python or TypeScript workflow code and who can operate a stateful distributed service. Self-hosted Temporal can be deployed with Docker Compose, Go binaries, Helm charts for Kubernetes, or a custom Go build. The deployment guidance says the services should run on hosts that are not reachable from the public internet, so network design matters. Many teams use a partner for the first migration wave and then take over operations. Decide early which parts you will keep in house, such as day-to-day operations, and which you will contract, such as upgrades or continuous support, and write that split into the scope.
Can Temporal take over workflows that are already running in Step Functions?
Not automatically. Step Functions execution state lives in AWS and cannot be transferred into a Temporal workflow history. The common approach is to let in-flight Step Functions executions finish, start new executions in Temporal, and cut over new work when the old queue drains. Long-running executions, such as those with multi-day Wait states, extend the overlap period, so the inventory should record the longest running execution for each state machine. Confirm this approach against your own execution history and retention needs before committing to a cutover date.
Can Amazon States Language definitions be converted to Temporal code automatically?
Definitions cannot be converted fully automatically in a way you should rely on for production. Amazon States Language describes states and transitions in JSON, while Temporal expresses control flow in ordinary code and models retries, timers and fan-out in the workflow itself. An export tool can produce an inventory of states, service integrations and IAM roles, which is useful for scoping. The translation of each state, especially Parallel, Map and callback patterns, is design work that needs review and testing. Ask for the export inventory as a deliverable, then have every converted workflow reviewed against its original behavior.
Should we choose self-hosted Temporal or Temporal Cloud?
Choose self-hosted Temporal when data residency, network isolation or ownership of the runtime is a requirement, and choose Temporal Cloud when you want Temporal Technologies to operate the service. Temporal Cloud pay-as-you-go pricing starts at 50 US dollars per million actions, with storage charges per GB-hour, a 99.9% SLA or 99.99% with high availability, and SAML SSO, according to Temporal's pricing page. Self-hosting removes per-action charges but adds database, search, staffing and on-call costs. Compare both options on your expected action volume, data location rules and staffing, and confirm current terms directly with Temporal before deciding.
How DeployOpen plans and runs the migration
DeployOpen plans, implements, hardens, documents and supports self-hosted open-source platforms inside the client's own infrastructure, and that includes self-hosted Temporal. For a move from AWS Step Functions, we start from a written scope that inventories the state machines and cuts them over in stages while both systems run.
How we scope
- Inventory every state machine, its Task, Choice, Wait, Parallel and Map states, and its service integrations
- Agree in writing which workflows move, which stay on Step Functions, and the cutover order
- Engagements are fixed-scope, with scope, deliverables and timelines agreed before work starts
How we build
- Translate state definitions into Temporal workflow code and activities, with signals replacing callback patterns
- Deploy Temporal in your environment with persistence and visibility sized to your execution volume
- Configure mTLS, namespace authorization, OIDC single sign-on for the Web UI and payload encryption before go-live
How we hand over
- Document workflow code, deployment topology, upgrade runbooks and the side-by-side cutover plan
- Run parallel execution tests and compare outcomes from both systems before retiring any state machine
- Transfer operational runbooks to your platform and on-call teams with recorded walkthroughs of the Web UI
How we support
- Ongoing support, server upgrades one minor version at a time, and continuous testing are available as a retainer
- Security testing of workflow APIs and the Temporal frontend can be scoped as a separate engagement
- Confirm with your team which upgrade path, persistence backend and retainer level fit your operating model

