Workflow Engine (Temporal, Cadence, AWS Step Functions)
Orchestrates long-running, stateful multi-step processes — the right tool when a business flow involves many services and can span days.
Why it exists
Some processes are hard: 'Charge the card, then update the shipping order, then send a confirmation email — and if any step fails, roll back the previous ones.' Doing this in application code means writing retry logic, compensation logic, state persistence, timeout handling, and observability yourself — every time. Workflow engines factor all of this out. You write the business logic; the engine handles durability, retries, and compensation.
How it works
A workflow is defined as code (Temporal, Cadence) or as a JSON state machine (Step Functions). Each step is an activity — a call to a service or a piece of business logic. The engine persists the workflow's state after every step. On worker failure, the engine reruns the workflow from the last checkpoint. Because activities may re-execute, they must be idempotent. Workflows can wait for external signals (user confirmation), sleep for days, and roll back via explicit compensation actions.
Scaling characteristics
Temporal / Cadence handle millions of concurrent workflows in production; state size per workflow is bounded (~100 KB) but total state can be terabytes. Latency per step is a few ms of engine overhead + the activity itself. Throughput scales with worker fleet + engine cluster; typical clusters run 100K workflow starts/sec.
When to use it
- Multi-service transactions (order → payment → inventory → shipping)
- Long-running processes (KYC, onboarding, subscription lifecycle)
- Human-in-the-loop flows (approval workflows)
- Compensating transactions across services (Saga pattern implementation)
- Retryable ML pipelines (data prep → training → deployment)
- Batch processing with complex step dependencies
When NOT to use it
- Simple synchronous requests — the overhead isn't worth it
- High-throughput low-latency work — the engine adds latency; a direct queue is faster
- Two-step processes where a queue + retry is enough
- You're already using Airflow and it works — don't switch just for the sake of it
Failure modes
- Non-idempotent activities cause corruption on retry — always design activities to be idempotent
- Workflow history grows unbounded on long-running workflows — use continueAsNew to reset
- Poison workflow: a bug in the code causes infinite retry — set retry limits + alerts
- Engine cluster overloaded from too many workflows — capacity plan carefully
- Debugging is harder than synchronous code — invest in observability early
Alternatives
- Choreographed sagas via events — no central engine; more moving parts to reason about
- A queue with retry — good for 2-step workflows; falls apart at 5+ steps
- Airflow — better for scheduled DAGs (batch); worse for event-triggered long-running flows
- Custom code + database state — reinventing the wheel; usually a mistake at any scale
Interview questions
- Explain the Saga pattern. When would you use a workflow engine to implement it vs. choreographed events?
- How do you handle a workflow that fails halfway through — resume from where it stopped or start over?
- Design a subscription-renewal workflow that runs monthly, retries on payment failure, and grace-periods before cancellation.
- What does 'idempotent activity' mean in Temporal, and why is it critical?
- Your workflow started before you deployed a code change. What happens when it resumes?
- How would you monitor the health of 10M concurrent workflows?
Systems that use this component
See how the real designs on this platform put workflow-engine to work — concrete usage context per system.
2014, Uber: some workflows run for weeks — where do you write that code?
A request-response cycle is a few hundred milliseconds. A background task is a few seconds. But what about workflows that legitimately need to run for hours, days, or weeks? An Uber Freight ship takes 3 days between waypoints. A Stripe payout batch runs monthly. A user onboarding sends emails over 30 days. If your program crashes at hour 27 of a 3-day workflow, you can't just retry from scratch — that's data corruption. You need durable execution.
For decades this problem was solved badly: cron jobs + state in a database + custom retry logic + custom timers, all glued together with prayer. Every team reinvented the same primitives and got them subtly wrong. Then in 2014, Uber's Cadence project (later open-sourced) codified the solution: durable execution. You write workflow code as if crashes couldn't happen. The engine transparently records every side effect and, on failure, replays the code to the exact point of the last recorded action.
The Cadence team (Maxim Fateev + Samar Abbas) spun out and built Temporal in 2019 — the modern industry standard. AWS Step Functions (2016) took the state-machine approach — you describe workflows as JSON, AWS executes them. Apache Airflow (2015) focused on data pipelines — DAGs of tasks, mostly scheduled. Prefect and Dagster modernized the data-workflow space. Whether you're building financial settlement, ML pipelines, or user onboarding — a workflow engine is the correct abstraction for "long, stateful, retryable" work.
The core insight: code is fragile; state is durable. A workflow engine flips this: you write straightforward code (loops, conditionals, awaits) and the engine makes it survive crashes by persisting every non-deterministic decision. Combined with retries, timeouts, and compensations, this lets you express "book flight then hotel; if hotel fails, refund flight" in 10 lines instead of 1000. The trade: your workflows must be deterministic (idempotent, no wall-clock, no random) so they can be replayed. That constraint is what makes durability possible.
Historical timeline
- 1970sBPM & workflow theoryBusiness process modeling emerges. Petri nets, workflow reference model. Ideas that would later become software.
- 1993Workflow Management CoalitionIndustry group standardizes workflow terminology + interchange formats.
- 2001BPEL (BPEL4WS)Business Process Execution Language for Web Services. XML orchestration. Complex + verbose but foundational.
- 2004jBPM open-sourcedJava-based workflow engine. First widely-used OSS BPM engine.
- 2008Cadence patterns paper (Hohpe)Enterprise Integration Patterns catalogs saga, compensating transaction, process manager.
- 2010Microsoft Workflow FoundationWF integrates workflow into .NET. Popular in enterprise. Predecessor of Durable Functions.
- 2014Uber builds CadenceMaxim Fateev + Samar Abbas build Cadence at Uber for durable orchestration. Amazon SWF inspired. Later open-sourced (2017).
- 2015Apache Airflow (Maxime Beauchemin at Airbnb)Python-first DAG-based scheduler. Focused on data pipelines. Explodes in data engineering.
- 2016AWS Step FunctionsServerless workflow. JSON state machine description. Deep AWS integration.
- 2016Azure Durable FunctionsMicrosoft ports the durable-execution idea into serverless. Uses replay-based determinism.
- 2018Prefect foundedJeremiah Lowin builds Prefect — modern Airflow alternative. Better DX, Python-native, dynamic workflows.
- 2019Temporal spun out of CadenceFateev + Abbas leave Uber, build Temporal — the polished commercial evolution of Cadence.
- 2019Dagster launchedNick Schrock builds Dagster — asset-first orchestrator. Data-quality focus.
- 2022Temporal Cloud GAManaged Temporal service. Removes ops burden. Adoption accelerates in fintech, ML, gaming.
- 2024AI-native workflowsLLM orchestration (LangChain, LlamaIndex) becomes a special case of workflow orchestration. Convergence with agents.
Durable execution: how Temporal survives crashes
The magic of a modern workflow engine is durable execution. Your code writes as if crashes can't happen; the engine records every activity result and replays deterministically on failure. Watch it play out:
1. Workflow starts
workflow.run() begins. Engine records: 'started' at t=0.
Sagas: distributed transactions without 2PC
Multi-service workflows need to coordinate transactions. Two-phase commit (2PC) doesn't scale in microservices — you can't hold locks across service calls. The answer is the Saga pattern: break a distributed transaction into a sequence of local transactions, each with a compensating action that undoes it if a later step fails.
Two-phase commit (won't work)
Coordinator: prepare Flight Flight: prepared (locked) Coordinator: prepare Hotel Hotel: prepared (locked) Coordinator: commit both // Locks held for whole distributed txn. // Coordinator crashes = locks stuck forever.
Requires shared coordinator + tight coupling. Locks span services. Cascading failures.
Saga (works!)
workflow:
try:
flight = bookFlight() // committed
hotel = bookHotel() // committed
charge = chargeCard() // committed
catch (err):
// Run compensations in reverse:
refundCard(charge) // if reached
cancelHotel(hotel) // if reached
cancelFlight(flight) // if reachedEach step is a local transaction. Failure triggers compensations. Eventual consistency.
Compensating actions — the semantics of undo
A compensating action isn't a rollback — you can't rollback across service boundaries. It's a business-level reversal: cancel the booking, refund the card, send an apology email. Design them deliberately:
Idempotent
Running the compensation twice = same result as once. Refund transaction ID X even if already refunded.
Reversibility asymmetry
You can't always "undo." Emails already sent. SMS delivered. Design the workflow so those actions happen LAST after all reversible steps.
Retry with backoff
Compensations may fail too. Retry with exponential backoff. Alarm if compensation stuck past N tries.
Orchestration vs Choreography — two workflow architectures
Two philosophies for multi-service workflows:
Orchestration (Temporal, Step Functions)
A central workflow engine drives each step. Explicit workflow code.
workflow orchestrator: bookFlight() bookHotel() chargeCard() sendConfirmation()
Choreography (event-driven)
Each service reacts to events from previous steps. No central coordinator.
FlightService: on FlightRequested → book → emit FlightBooked HotelService: on FlightBooked → book → emit HotelBooked PaymentService: on HotelBooked → charge → emit Charged EmailService: on Charged → send
Product comparison
| Product | Type | Model | Strength | Weakness |
|---|---|---|---|---|
| Temporal | Durable execution | OSS + Cloud | Best-in-class DX. Code-as-workflow. Multi-language (Go, Java, TS, Python). | Ops complexity for self-hosted. Cost at scale for Cloud. |
| Cadence (Uber) | Durable execution | OSS | Temporal's ancestor. Battle-tested at Uber. Java + Go. | Smaller ecosystem than Temporal. Uber-centric roadmap. |
| AWS Step Functions | State machine | Managed | Serverless. Deep AWS integration. Visual designer. Pay-per-transition. | JSON state machine can get ugly. AWS-only. Cost at scale. |
| Apache Airflow | DAG scheduler | OSS | Standard for data pipelines. Huge community. Python-native. | Not for long-running (hours) work. Scheduler is a bottleneck. UI slow. |
| Prefect | Modern data workflow | OSS + Cloud | Better DX than Airflow. Dynamic DAGs. Hybrid execution. | Smaller than Airflow. Cloud tier costs. |
| Dagster | Asset-first workflow | OSS + Cloud | Data quality + lineage first-class. Testable pipelines. | Younger. Learning curve for asset model. |
| Argo Workflows | K8s-native DAG | OSS (CNCF) | Runs each step as a K8s pod. Fits K8s-first orgs. GitOps friendly. | K8s-only. Kubernetes ops complexity. |
| Azure Durable Functions | Durable execution | Managed | Serverless. .NET-native. Replay-based determinism. | Azure-only. Cold start latency. C# / Python biased. |
| GCP Cloud Workflows | State machine | Managed | YAML-defined. GCP integration. Pay-per-execution. | GCP-only. Less powerful than Step Functions. |
| Restate | Durable execution + RPC | OSS + Cloud | Newer. Combines durable execution with RPC semantics. Simpler mental model. | Very new (2023). Ecosystem building. |
| Netflix Conductor | Orchestration | OSS | Netflix-scale. JSON workflow definition. Language-agnostic. | Older architecture. Ops complexity. |
| Camunda BPMN | BPMN-based | OSS + Enterprise | Business-analyst-friendly (BPMN diagrams). Enterprise features. | BPMN is verbose. Java-centric. Slower iteration than code-based. |
How to choose: Business workflows with long-running steps → Temporal (or Cloud) for modern code-as-workflow. AWS shop + simple state machines → Step Functions. Data pipelines → Airflow (community) or Dagster (modern). Kubernetes-native → Argo Workflows. Business-analyst-driven → Camunda.
12 real-world workflow engine deployments
Cadence for driver/rider matching + more
Uber uses Cadence for hundreds of workflows: driver onboarding, matching, payments, rating disputes, dynamic pricing. Some run for weeks. Cadence handles retries, timeouts, human intervention.
Temporal for money movement
Coinbase runs Temporal for withdrawals, transfers, reconciliation. Financial correctness demands durable execution. Sagas across banking APIs + on-chain confirmations.
Airflow for the data platform
Airbnb built Airflow. Powers thousands of daily DAGs — data warehousing, ML training, business reports. Standard tool of the data engineering world.
Conductor for content processing
Netflix built Conductor for video processing pipelines. Each new title triggers a workflow that transcodes, generates thumbnails, distributes to Open Connect. Handles retries + partial failures gracefully.
Homegrown workflow engine
Stripe built a custom workflow engine for payouts, disputes, subscription renewals. Runs at massive scale. Interesting design constraint: idempotency + auditability at every step.
Temporal for signup + ads pipelines
Snap uses Temporal for user signup workflows (multi-step verification), ad campaign orchestration. Scales to millions of concurrent workflows.
Cadence for order + delivery lifecycle
Every DoorDash order flows through a Cadence workflow: assign restaurant, dispatch dasher, track pickup, monitor delivery, handle refunds. 30+ minutes end-to-end.
Custom workflow for SMS delivery routing
Twilio's SMS routing runs on a custom workflow engine. Each message may go through multiple carriers, retries, geo-checks. Durable — no lost messages.
Custom + Temporal hybrid
Datadog runs SLO computation as Temporal workflows. Long-running aggregations that survive restarts. Also uses custom orchestration for high-volume metrics.
LLM training pipelines
OpenAI runs training pipelines on internal orchestration + Airflow-like tools. Fine-tuning jobs, evaluation runs — all as workflows with retries + checkpointing.
Temporal for merchant sync + checkout
Shopify uses Temporal for third-party sync workflows (Amazon, eBay integrations), checkout multi-step processes. Handles retries when partner APIs flake.
Airflow + custom for ML + logistics
Instacart runs Airflow for data + ML pipelines. Custom logistics orchestration for shopper dispatch. Hybrid data + operational workflow story.
Key takeaways
- 1A workflow engine is durable execution — code that survives crashes by journaling every side effect.
- 2You need one when work spans minutes to weeks, has multiple failure-prone steps, or coordinates across services.
- 3Sagas replace 2PC in microservices: sequence of local transactions with compensating actions on failure.
- 4Compensations must be idempotent. Retry-safe. Design workflows to put irreversible side effects LAST.
- 5Orchestration (central engine) for critical flows. Choreography (event-driven) for loose coupling. Mix consciously.
- 6Determinism constraint: workflow code can't use wall-clock, random, or file I/O directly. That's how replay works.
- 7For code-as-workflow: Temporal is state-of-the-art. For data pipelines: Airflow. For AWS-native: Step Functions.
- 8Cron is not a workflow engine. If you find yourself building retry + state in your cron job, you need one.
References & further reading
- • Garcia-Molina, H. & Salem, K. (1987). "Sagas." The foundational sagas paper.
- • Hohpe, G. & Woolf, B. (2003). Enterprise Integration Patterns. Catalog of process manager, saga, compensating transaction.
- • Fowler, M. (2015). "Orchestration vs Choreography." Blog post.
- • Newman, S. (2015). Building Microservices. Excellent chapter on sagas + orchestration.
- • Fateev, M. & Abbas, S. (2020). "Temporal Whitepaper." The definitive intro to durable execution.
- • Amazon (2016). "Introducing AWS Step Functions." Announcement blog + docs.
- • Beauchemin, M. (2016). "The Rise of the Data Engineer." Airflow context.
- • Uber Engineering (2017). "Introducing Cadence." Origin story of the modern durable execution paradigm.
- • Temporal Docs: "Concepts" section. Best conceptual guide to workflows + activities + tasks.
- • Kleppmann, M. (2017). DDIA, chapter 9 (Consistency + Consensus) provides theoretical grounding.