Temporal
Business processes rarely fit in one request. An order is charged, then waits for stock, then ships, and may be canceled along the way; a subscription renews monthly for years; an onboarding flow waits days for a document upload. Building these with queues, cron jobs, and status columns produces fragile state machines spread across services, where a crash at the wrong moment leaves an order charged but never shipped. Temporal lets you write such processes as ordinary code — charge(), await a signal, sleep(30 days), ship() — and guarantees that the code runs to completion despite process crashes, deploys, and outages.
It does this by recording every step of a workflow in an event history and replaying that history to rebuild state after a failure. The trade-off is a discipline: workflow code must be deterministic, and all side effects go through activities.
TL;DR
- Workflows orchestrate a process in deterministic code; activities perform side effects (API calls, database writes) with retries.
- Workers poll task queues and run your workflow and activity code; the Temporal Service stores state and history.
- Workflow state is rebuilt by replaying event history, so workflow code must avoid randomness, system time, and I/O.
- Configure activity timeouts, retry policies, and heartbeats; make activities idempotent.
- Interact with running workflows through signals, queries, and updates; use durable timers for waits of any length.
- Change running workflow code safely with versioning, and test with time skipping and replay tests.
Quick Example
An order workflow in the Python SDK: charge the card, allow cancellation for an hour, then ship or refund.
Starting it, with the order ID as the workflow ID so duplicate starts are rejected:
Core Concepts
Workflows, Activities, and Workers
Workers are ordinary services you deploy and scale. The Temporal Service never runs your code; it records what happened and tells workers what to do next.
Event History and Determinism
Every workflow decision — an activity scheduled, a timer started, a signal received — is recorded in the workflow's event history. When a worker picks up a workflow after a crash, it replays the code against the history to reconstruct state, then continues. For replay to work, workflow code must make the same decisions every time:
- Use the SDK's time and random functions (for example
workflow.now()), not system clocks or random generators. - Perform all I/O and side effects in activities.
- Avoid iterating over unordered collections or depending on threads.
SDKs help: the Python and TypeScript SDKs sandbox workflow code, and all SDKs detect nondeterminism during replay.
Activities, Timeouts, and Retries
Activities are retried automatically according to a retry policy (initial interval, backoff, maximum attempts, non-retryable error types). Timeouts bound each part of execution:
Because activities may run more than once, make them idempotent — for example, with idempotency keys for payments. See Idempotency.
Signals, Queries, and Updates
- Signals deliver asynchronous input to a running workflow (cancel, approve, add item).
- Queries read workflow state without changing it.
- Updates combine both: a synchronous request that can validate input, change state, and return a result.
Timers, Child Workflows, and Long Histories
Durable timers let workflows wait minutes or months without holding resources. Child workflows split large processes and isolate failure domains. Very long-running workflows (subscriptions, entity workflows) use continue-as-new to start a fresh history periodically, keeping replay fast.
Versioning Running Workflows
Workflows may run for weeks while you deploy new code. Changing the sequence of steps can break replay for workflows already in flight. Options:
- Patching (
workflow.patched()in Python,GetVersionin Go and Java): branch on a version marker so old executions follow old logic and new ones follow new logic. - Worker versioning: route workflows to workers running the code version they started with.
- New workflow types for large changes, letting old ones drain.
Replay tests against recorded production histories catch incompatible changes before deploy.
Testing
- Unit test activities as normal functions.
- Test workflows with time skipping: the SDK's test environment fast-forwards timers, so a workflow that waits a month finishes in milliseconds.
- Mock activities in workflow tests to exercise failure and retry paths.
- Replay tests: download event histories of real executions and replay them against new code in CI to detect nondeterminism.
Temporal and Alternatives
Best Practices
Keep Workflows Pure and Activities Small
Put all external interaction in activities, each doing one retryable thing; keep workflow code as readable orchestration.
Use Business Identifiers as Workflow IDs
A workflow ID such as order-o-123 makes starts idempotent and lets any service signal or query the right execution.
Set Explicit Timeouts
Always set start-to-close timeouts and heartbeats for long activities, so stuck work is detected and retried.
Plan for Versioning From Day One
Assume workflows will be running when you deploy changes. Use patching or worker versioning and run replay tests in CI.
Common Mistakes
Nondeterministic Workflow Code
Non-Idempotent Activities
Unbounded Histories
FAQ
What is Temporal?
A durable execution platform that runs workflow code reliably: it records each step in an event history, retries failed activities, and resumes workflows after crashes or deploys by replaying their history.
What is the difference between a workflow and an activity?
A workflow is deterministic orchestration logic whose state Temporal persists. An activity is a function that performs side effects — calling APIs, writing to databases — and can be retried and time-limited.
Why must Temporal workflows be deterministic?
Because Temporal rebuilds workflow state by replaying code against the recorded event history. Nondeterministic code could make different decisions during replay, corrupting the workflow's state.
How do I change a workflow that is already running?
Use versioning: patch markers that keep old executions on old logic, worker versioning that routes executions to compatible workers, or new workflow types. Validate with replay tests.
Is Temporal open source?
Yes. The Temporal Service and SDKs are open source under the MIT license, and Temporal Technologies offers Temporal Cloud as a managed service.
Related Topics
- Durable Execution — The broader concept and alternatives
- Saga Pattern — Coordinating multi-step transactions
- Idempotency — Making retried activities safe
- AWS Step Functions — A managed workflow service
- Microservices — Orchestrating work across services
- Python — The SDK language in the examples