temporalio / temporal
Temporal makes long-running application logic recoverable, not effortless
The server persists workflow history while user-owned workers replay deterministic code and execute side effects as activities. It can replace piles of retry and timer plumbing, provided teams accept a new programming and operating model.
WHAT TO KNOW FIRST
- Temporal stores an append-only event history and replays workflow code to reconstruct state, so workflow logic must remain deterministic across retries and deployments.
- Activities contain side effects and may be attempted more than once. Timeouts, retries, heartbeats, cancellation, and idempotency are application contracts, not automatic exactly-once execution.
- The MIT-licensed server can be self-hosted, while Temporal Cloud is a separate managed service. SDKs, deployment tooling, and persistence choices must be evaluated with the server.
01Durable execution is built from recorded decisions
Temporal represents a running business process as a Workflow Execution. The service records events such as workflow start, task completion, timers, activity scheduling, signals, and results in an append-only history. When a worker process disappears, the logical workflow is not reduced to whatever lived in that process's memory. Another compatible worker can rebuild state from the history and continue.
This is different from periodically serializing an arbitrary application object. Workflow code is re-executed against recorded events, and commands produced during replay must match prior decisions. The result feels like a durable function that can wait a long time without holding a thread. The cost is a programming contract around determinism, payloads, event history, and code evolution. Temporal preserves progress only for behavior expressed through its model.
02Workflows decide, activities touch the outside world
A Workflow Definition contains orchestration logic: sequencing, branching, timers, messages, and calls to activities or child workflows. It should avoid unrecorded side effects and nondeterministic APIs. An Activity performs work that can fail independently, such as calling a payment service, sending a message, writing to another database, or running a computation outside deterministic workflow constraints.
The separation makes failure policy visible. A workflow can wait durably for an activity result and decide what follows, while the activity has timeouts, retries, and cancellation behavior suited to the external operation. Do not turn every function into an activity, because each boundary creates tasks and history. Do not hide side effects inside workflow code, because replay may run that code again. Draw the boundary where nondeterministic work or an independent failure unit actually begins.
03Replay makes ordinary code carry a versioned history
During replay, the SDK runs workflow logic and compares generated commands with events already stored. Reading the wall clock directly, choosing an uncontrolled random value, iterating an unordered collection whose order changes, or making network calls can produce a different path. SDKs provide deterministic alternatives for common needs and document language-specific constraints. Those rules belong in code review and tests.
Deployments add a subtler risk. A workflow that started under old code may replay after new code changes a branch or command order. Temporal SDKs provide patching or worker-versioning mechanisms according to their current capabilities, but a team still needs a compatibility strategy. Keep long-lived workflow types stable, run replay tests against saved histories, and remove old code only after executions that require it are complete or deliberately migrated. Application deployment now includes past decisions.
- Use SDK-provided time, random, sleep, and side-effect mechanisms inside workflows.
- Replay representative production histories before deploying workflow code changes.
- Keep activity implementation changes compatible with payloads already waiting in task queues.
04Task queues connect durable state to user-owned workers
Temporal does not run application code inside the server repository. Worker processes built with an SDK poll task queues, execute workflow tasks or activity tasks, and return commands or results. Task queues route work by name and can support separate worker pools for capabilities, regions, or deployment versions. The Temporal service owns durable coordination; the application team owns worker code and capacity.
A backlog can mean insufficient workers, unavailable dependencies, a bad deployment, or deliberate rate control. Monitor schedule-to-start latency, task failures, pollers, and activity duration rather than only workflow completion. Task queue names are an interface between starters and workers, so version and configure them intentionally. A worker that registers the wrong activities can create repeated failures, while an overbroad worker identity may reach external systems unrelated to its assigned workflows.
05Retries cannot create exactly-once side effects
Activities can be retried after failures or timeouts according to policy. If an activity performs an external action and loses its response, Temporal may have no proof whether the action happened. A later attempt can repeat it. The architecture documentation therefore frames activities as idempotent or explicitly non-retryable according to the desired at-least-once or at-most-once behavior.
Use stable business identifiers with external APIs, transactional outboxes, deduplication records, or read-before-write reconciliation where appropriate. Choose start-to-close, schedule-to-close, and schedule-to-start timeouts from distinct failure questions. Long activities can heartbeat progress and receive cancellation, but heartbeat details and retry behavior should be tested. Retry only failures likely to recover and cap backoff. A permanent validation error should not consume hours of attempts while the workflow appears merely busy.
06Messages and timers make waiting explicit
Signals deliver asynchronous information to a workflow, queries read workflow state without advancing it, and updates support tracked request-response interactions according to SDK support and server behavior. Durable timers let workflow code wait without occupying a worker thread. These mechanisms fit approval callbacks, cancellation, address changes, and deadlines that otherwise become database flags plus scheduler scans.
Message handlers can interleave with workflow progress, so state invariants still need careful code. Use workflow IDs that express business identity and define how duplicate starts or messages are handled. Validate message payloads, authorize calls at the service boundary, and decide what happens when a message arrives before the expected state. Queries are not a substitute for an indexed reporting store at high analytical volume. Temporal visibility and workflow state serve operations, not every product read model.
07History is the recovery source and a bounded resource
Every relevant workflow transition adds events and payload metadata to history. Very long or high-frequency workflows can approach service limits and become expensive to replay. Continue-As-New starts a fresh run in the same workflow chain with new input, preserving logical continuity while bounding one run's history. Child workflows can separate lifecycles, but they add coordination and should follow a domain boundary.
Do not place large documents or secrets casually in workflow inputs, results, memos, search attributes, or activity payloads. Histories can be retained, viewed, and exported according to deployment policy. Use payload codecs or external references where the threat model requires them, and keep encryption keys independently managed. Track history length and size before limits become failures. A process that loops forever needs a continuation plan at design time, not after years of events accumulate.
08Self-hosting means operating a distributed control system
The server architecture separates frontend, history, matching, and internal worker services. History shards manage workflow state, matching serves task queues, and persistence stores durable records. A self-hosted deployment must provision supported databases, visibility, networking, identity, TLS, capacity, backups, upgrades, and service health. Running the development container is useful for learning but does not demonstrate a recoverable production cluster.
Temporal Cloud moves server operation to a managed service, while application workers and their external credentials remain the customer's responsibility. Evaluate namespace isolation, connectivity, regional design, retention, encryption, quotas, observability, and disaster objectives for either option. Self-host only when platform ownership is real. The value of durable workflows disappears if the cluster's persistence cannot be restored or if workers have no tested path to reconnect during an incident.
09Adopt it where failure spans time and systems
Temporal earns its complexity when a process crosses services, waits for people or callbacks, uses durable timers, and must explain exactly where it stopped. It can consolidate custom retry tables, cron scans, queue chains, and compensating state machines into code plus history. Start with one painful workflow whose owners can compare current incident load with the new model.
It is a poor replacement for one local database transaction or a simple fire-and-forget job. The temporalio/temporal server is MIT licensed, while SDKs are separate repositories and Temporal Cloud has separate commercial terms. Review each artifact and release line. The most honest pilot includes worker outage, duplicate activity attempt, incompatible code change, and operator recovery. A green happy path demonstrates syntax; recovery behavior demonstrates the platform.
A SENSIBLE FIRST HOUR
Start small enough to learn the repo
- Choose one official SDK and run its current local development setup, then implement a workflow with one activity, one durable timer, and one explicit input and result type.
- Stop the worker while the workflow waits, restart it, and inspect the event history to see how execution resumes instead of trusting a happy-path demo.
- Force the activity to fail after performing a side effect, add an idempotency key and retry policy, and verify the external system does not receive an unintended duplicate.
- Before production, define task queues, worker ownership, deployment compatibility, history limits, payload security, namespace policy, observability, and the responsibility split between self-hosting and Temporal Cloud.
SOURCE LEDGER
What this review is built on
We use the project repository and first-party documentation. Access, licenses and project direction can change, so recheck the linked source before making a production decision.