Markdown Editor

Workflow Orchestration Engine System Design Template

Durable workflow engine design: event history and replay, deterministic code, activities, timers, task queues, retries, versioning, visibility, history sharding

使い方: Use it when you design, adopt or review a durable execution engine for long-running multi-step processes. Fill the open-workflow and timer estimates (3.3) and the determinism and versioning rules (7.1, 7.4) first. The main pitfall is workflow code that behaves differently on replay; require replay tests in CI.

プレビュー

System Design: [Workflow orchestration engine name]

Reference design for a durable workflow orchestration engine: a platform that runs long-lived business processes written as ordinary code (order fulfilment, account onboarding, payment sagas, data pipelines) and guarantees that they resume exactly where they stopped after crashes, deploys and outages. It covers the event history and replay model, deterministic workflow code, activities, durable timers, task queues and matching, retries and timeouts, workflow code versioning, visibility search and sharding of history. It is distinct from the Job Scheduler System Design Template (system-design/design-job-scheduler), which runs independent jobs on a schedule; this engine coordinates multi-step stateful processes. It follows the structure of the System Design Document template and is pre-filled with a worked design to adapt. Replace every [bracketed] value and every row marked Example; all numbers are illustrative assumptions, not benchmarks.

Document control

FieldValue
Document ID[SDD-WF-001]
System / feature[Durable workflow orchestration platform]
Version[0.1]
Status[Draft / In review / Approved / Implemented / Superseded]
Owner[@owner]
Author(s)[@author]
Reviewers[@reviewer-1], [@reviewer-2]
Last updatedYYYY-MM-DD
Classification[Internal]
Build or adopt[Build / adopt open-source engine / managed service]
RelatedJob Scheduler System Design Template (system-design/design-job-scheduler), Message Queue System Design Template (system-design/design-message-queue), Event Sourcing and CQRS Template (architecture/event-sourcing-cqrs)

Approvals

RoleNameDecisionDate
Tech lead, platform[@name][Approved / Changes requested]YYYY-MM-DD
Staff / principal engineer[@name][Decision]YYYY-MM-DD
SRE / operations[@name][Decision]YYYY-MM-DD
Data / storage owner[@name][Decision]YYYY-MM-DD
Security[@name][Decision]YYYY-MM-DD

Revision history

VersionDateAuthorChange summary
0.1YYYY-MM-DD[@name]First draft for design review
0.2YYYY-MM-DD[@name]Example: Raised shard count from 1,024 to 4,096 after open-workflow estimate
0.3YYYY-MM-DD[@name]Example: Added sticky task queues to cut replay cost
1.0YYYY-MM-DD[@name]Example: Approved

Contents

1. Overview

1.1 Problem statement

[Example: Order fulfilment spans payment, inventory, warehouse and shipping services and can take from minutes to 14 days. Today the state machine is spread across 9 queues, 4 cron jobs and a status column in the orders table. After a broker outage last month, 3,200 orders were stuck in "payment captured, not reserved" and took two engineers four days to repair by hand. Every new process repeats the same plumbing: retries, timeouts, compensation and status pages.]

1.2 Proposed solution

[Example: A shared engine stores each workflow execution as an append-only event history. Workflow code runs in worker processes owned by product teams; it is replayed from the history to rebuild state, so it must be deterministic. Side effects run as activities with their own retry and timeout policies. The engine provides durable timers, signals and queries, and dispatches workflow and activity tasks through partitioned task queues. Histories are sharded by workflow ID across a fixed number of shards, each owned by one history host at a time. A visibility store indexes executions for search, and closed histories are archived to object storage after a retention period.]

1.3 Decisions requested from reviewers

IDQuestionRecommended optionSection
Q-01Example: Build, adopt open source or use a managed service?Adopt an open-source engine or managed service unless a hard constraint rules both out10
Q-02Example: How many history shards?4,096, fixed at cluster creation3.4, 7.2
Q-03Example: How do teams change workflow code safely?Version markers in code plus worker build versioning7.4
Q-04Example: What is the delivery guarantee for activities?At least once; activities must be idempotent7.5
[Q-nn][Question][Option][Section]

1.4 45-minute interview path

MinutesCoverKey point to land
0 to 5Scope: long-running multi-step processes, not cron jobsDurability across crashes is the product
5 to 10Core requirements and guarantees: workflow state never lost, activities at least onceExactly-once side effects are not promised
10 to 15Estimates: starts per second, events per workflow, open workflows, pending timersOpen workflows times duration sizes storage and timers
15 to 20Model: workflow, activity, event history, task queue, timerHistory is the source of truth
20 to 25High-level diagram: frontend, history shards, matching, workers, visibilityEngine never runs user code
25 to 38One deep dive: event history and replay with determinism (7.1) is the core; sharding and the transfer queue (7.2) or versioning (7.4) are good alternativesExplain why non-deterministic code breaks replay
38 to 42Failure modes: shard host loss, worker crash, poisoned workflowShard ownership moves; workers retry
42 to 45Trade-offs and what changes at 10xHistory store write rate binds first

2. Requirements

2.1 Core functional requirements

IDRequirementPriority
FR-01Example: Start a workflow by type and ID; reject or reuse duplicates per policyMust
FR-02Example: Run activities with retry policy (initial interval, backoff, maximum attempts) and timeoutsMust
FR-03Example: Durable timers from seconds to 365 daysMust
FR-04Example: Signals (external events into a running workflow) and queries (read workflow state)Must
FR-05Example: Child workflows and cancellation that propagates to childrenMust
FR-06Example: Search executions by type, status, start time and custom attributesMust
FR-07Example: Safe deployment of changed workflow code while old executions are runningMust
FR-08Example: Reset a workflow to an earlier point after a bug fixShould
FR-09Example: Schedules (cron-style starts) for workflowsShould
[FR-nn][Requirement][Must / Should / Could]

2.2 Non-functional requirements

IDQualityTargetMeasured as
NFR-01DurabilityExample: No acknowledged workflow event is lost (RPO 0 within a region)Fault injection on storage
NFR-02Start latencyExample: p99 below 100 ms to acknowledge a startFrontend timing
NFR-03Dispatch latencyExample: p99 below 50 ms from task scheduled to task delivered when a worker is pollingMatching metrics
NFR-04ThroughputExample: 5,000 starts/s and 100,000 history events/s at peakLoad test
NFR-05Timer accuracyExample: Timers fire within 1 s of due time at p99Timer lag metric
NFR-06IsolationExample: One namespace's surge does not raise another's dispatch latency above targetMulti-tenant load test
[NFR-nn][Quality][Target][Measurement]

2.3 Below the line (out of scope)

  • [Example: running user code inside the engine (workers run in teams' own services)]
  • [Example: exactly-once side effects in external systems (activities are at least once; idempotency is the caller's job)]
  • [Example: high-throughput stream processing (use the message queue and a stream processor)]
  • [Example: simple scheduled jobs without multi-step state (Job Scheduler System Design Template, system-design/design-job-scheduler)]
  • [Example: a visual workflow designer for non-engineers]

3. Capacity estimation

3.1 Assumptions

InputValueSource
Workflow starts per second, peakExample: 5,000Product forecasts summed across teams
History events per workflow, averageExample: 20Pilot workflows
Event size, averageExample: 1 KBPilot payloads (large payloads by reference)
Average time a workflow stays openExample: 2 hours (7,200 s)Mix of short and multi-day workflows
Pending timers per open workflowExample: 2Pilot workflows
Workflow tasks plus activity tasks per workflowExample: 8 + 6 = 14Pilot workflows
Closed-history retention in primary storeExample: 7 daysSupport needs
Storage replication factorExample: 3Storage design

3.2 History write rate

5,000 starts/s x 20 events = 100,000 events/s; at 1 KB that is 100 MB/s of history, 300 MB/s of disk writes with 3 replicas.

Consequence: the history store must sustain six-figure appends per second with low latency, which rules out a single relational primary. Use a horizontally partitioned store and keep events small: payloads above Example: 256 KB go to object storage and the event carries a reference.

3.3 Open workflows and timers

Open workflows = 5,000 starts/s x 7,200 s = 36 million. Pending timers = 36 million x 2 = 72 million.

Consequence: timers cannot live only in memory. Each shard keeps a durable timer queue ordered by fire time and loads only the next Example: few seconds of timers into memory.

3.4 Shards

With 4,096 shards, the average shard takes 100,000 / 4,096 = about 24 events/s and holds 36 million / 4,096 = about 8,800 open workflows. On 64 history hosts each host owns 64 shards, about 1,560 events/s.

Consequence: shard count is fixed at cluster creation because workflow IDs hash to shards permanently. Pick a count that leaves room for 10x growth (4,096 allows hosts to grow to several hundred before a shard becomes the unit of contention).

3.5 Task dispatch

5,000 workflows/s x 14 tasks = 70,000 task dispatches/s.

Consequence: a single task queue partition cannot serve the busiest queues. Partition each task queue (Example: 4 to 16 partitions for busy queues) and prefer synchronous matching to a waiting poller over persisting the task.

3.6 Retention

100 MB/s x 86,400 s x 7 days = about 60.5 TB of history, about 181 TB with 3 replicas.

Consequence: the primary store keeps only open workflows plus 7 days of closed ones; closed histories are archived to object storage, where a year costs much less per TB.

3.7 Summary

QuantityEstimateDesign consequence
History events100,000/sPartitioned history store; payloads by reference
Open workflows36 millionDurable mutable state per workflow, cached on owner host
Pending timers72 millionDurable per-shard timer queues
Shards4,096 on 64 hostsFixed shard count, ownership via membership
Task dispatch70,000/sPartitioned task queues, sync match
Retentionabout 181 TB replicated for 7 daysArchive closed histories

4. API design

4.1 Interfaces

InterfaceOperationPurpose
Client APIStartWorkflow(namespace, workflow_id, type, task_queue, input, id_reuse_policy)Start an execution
Client APISignalWorkflow(workflow_id, signal_name, payload)Deliver an external event
Client APIQueryWorkflow(workflow_id, query_name)Read state from the workflow (served by a worker)
Client APICancelWorkflow / TerminateWorkflowGraceful cancel versus hard stop
Client APIListWorkflows(query)Search visibility records
Worker APIPollWorkflowTask(task_queue) / RespondWorkflowTaskCompleted(commands)Run workflow code and return commands
Worker APIPollActivityTask(task_queue) / RespondActivityTaskCompleted(result)Run an activity
Worker APIRecordActivityHeartbeat(details)Liveness and progress for long activities

4.2 Workflow code example

# Example: workflow and activity in an SDK of this engine (pseudocode)
@workflow
def fulfil_order(order):
    payment = activity(capture_payment, order, retry=Retry(initial=1s, backoff=2.0, max_attempts=10),
                       start_to_close=30s)
    try:
        activity(reserve_stock, order, start_to_close=60s)
    except ActivityFailed:
        activity(refund_payment, payment)          # compensation
        raise
    shipped = wait_for_signal("shipped", timeout=days(14))   # durable timer + signal
    if not shipped:
        activity(open_support_case, order)
    return "done"

Workflow code may only call engine APIs for anything non-deterministic: time (workflow.now()), random values, UUIDs, sleeps and I/O all go through the SDK so they are recorded in history.

4.3 Errors and idempotency

SituationBehaviour
Start with an ID that is already runningALREADY_STARTED error, or return the running execution, per reuse policy
Signal to a closed workflowNOT_FOUND; caller decides whether to start a new one
Activity completion after timeoutRejected; the retry already owns the attempt
Duplicate completion from a retried worker callIgnored using the task token and attempt number

5. Data model

5.1 Entities

Each execution has one history and one mutable state row, both in the same shard so they can be updated in one transaction.

5.2 Storage choices

DataStoreWhy
History events, mutable state, timer and transfer tasksExample: Wide-column or distributed SQL store, partitioned by shardHigh append rate; per-shard transactions
Task queues (backlog only)Same store, partitioned by task queue partitionPersist only when no poller is waiting
Visibility recordsExample: Search index (fed asynchronously)Flexible queries without loading the history store
Large payloadsObject storage, referenced from eventsKeeps events small
Archived historiesObject storage, compressedCheap long retention

5.3 Access patterns

QueryServed byKey or indexPartition rationale
Append events and update state for workflow WHistory store(shard_id, workflow_id, run_id)Shard = hash(namespace, workflow_id) mod 4,096, so one workflow's writes stay in one shard transaction
Read full history for replayHistory store(run_id, event_id range)Sequential read within a partition
Timers due in the next N seconds on shard STimer queue(shard_id, fire_time, task_id)Range scan per shard; no global timer index
Tasks to hand to matching or visibilityTransfer queue(shard_id, task_id)Written in the same transaction as the event (outbox)
Next task for task queue QMatching backlog(task_queue, partition, task_id)Partitions spread hot queues
Workflows of type T failed in the last hourVisibility index(namespace, workflow_type, status, close_time)Search index, eventually consistent

6. High-level design

The engine schedules work; workers in product teams' services execute it.

ComponentResponsibilityScales by
FrontendAuthentication, rate limits per namespace, routing to the owning shardStateless instances
History serviceOwns shards; appends events, runs timer and transfer queuesHosts; shards move between hosts
Matching serviceTask queue partitions; matches tasks to long-polling workersPartitions per queue
WorkersRun workflow code (replay) and activitiesOwned and scaled by teams
Visibility indexerFeed search index from transfer tasksIndex cluster
ArchiverMove closed histories to object storage after retentionBatch workers
Membership ringDecide which host owns which shardGossip or coordination service

7. Detailed design

7.1 Deep dive 1: event history, replay and determinism

OptionHow state survives a crashDeveloper experienceVerdict
A. Explicit state machine in a databasePersist state after each stepPlumbing in every serviceStatus quo; error-prone
B. Checkpoint serialised program stateSnapshot memory periodicallyFragile across code changesRejected
C. Event history plus deterministic replayRebuild state by re-running code against recorded resultsPlain code; strict rulesChosen

Choice: C. Reason: the history records every decision and result, so state can always be rebuilt and audited, and the code reads like a normal function. The cost is the determinism contract.

How one workflow task works:

Determinism rules for workflow code:

  • Same history in, same commands out. Never read the system clock, random numbers, environment variables or configuration directly; use SDK equivalents that record their values.
  • No direct I/O (network, files, database). Wrap it in an activity.
  • No native threads or unordered iteration that changes command order; use SDK coroutines and ordered collections.
  • On replay, the SDK compares produced commands with recorded events and fails the task with a non-determinism error on mismatch rather than corrupting state.
  • Keep histories bounded: when a workflow loops (for example, a subscription that runs for years), restart it as a fresh run with its current state ("continue as new") before the history grows past a configured cap (Example: 10,000 events warning, 50,000 events hard limit).

Sticky execution: after a task completes, the worker keeps the workflow's state in memory and the next task is offered first to that worker's own queue, so the full history is replayed only after a cache miss or worker restart.

7.2 Deep dive 2: history sharding and the transfer queue

OptionConcurrency controlVerdict
A. Any host handles any workflow, locking in the databaseRow locks per workflowLock contention and no ordering of timers
B. Partition by workflow, one owner per shardOwner serialises updates; fencing token on writesChosen
C. One actor per workflow placed dynamicallyFine-grained placementToo many placement records at 36 million open workflows

Choice: B. Reason: one owner per shard makes appends ordered and lets the owner cache mutable state. Each write carries the shard's range_id; when ownership moves, the new owner increments it so writes from the old owner fail (fencing).

Every state change that must cause work elsewhere (dispatch a task, update visibility, signal a child) is written as a transfer task in the same transaction as the events. A per-shard processor reads the transfer queue and calls matching or the indexer, retrying until acknowledged. This is the transactional outbox pattern: it avoids the dual-write problem where the event is stored but the task is never dispatched. The timer queue works the same way, keyed by fire time.

7.3 Deep dive 3: task queues and matching

  • Workers long-poll a task queue; matching hands a new task directly to a waiting poller (sync match) and persists it only if no poller is waiting.
  • Busy queues are split into partitions; pollers and tasks are spread across partitions, and idle partitions forward to a root partition so a single poller still receives every task.
  • Rate limits per task queue protect downstream systems that activities call; they are configured by the owning team.
  • Backlog age per queue is the main capacity signal for workers: a growing backlog means the team needs more workers, not that the engine is slow.
Option for dispatchLatencyStorage writesVerdict
A. Always persist, workers poll storageHigherOne write and delete per taskSimple but costly at 70,000 tasks/s
B. Push to workersLowNoneEngine must track worker capacity
C. Long poll with sync match, persist on backlogLowOnly when backloggedChosen

7.4 Deep dive 4: versioning workflow code

Changing workflow code while executions are open breaks replay if the new code produces different commands for an existing history.

OptionHow it worksVerdict
A. Never change running workflows; new type name per changeOld and new code side by sideSimple but clutters types
B. Version markers in codeif workflow.version("add-fraud-check", 1) >= 1: records which branch an execution tookChosen for small changes
C. Worker build versioningExecutions stay pinned to the worker build that started them; new builds take new executionsChosen for large changes

Choice: B for small changes and C for large ones. Reason: markers keep one code base and are replay-safe; build pinning avoids a branch explosion for big rewrites. Before deploying, run a replay test that feeds recent production histories (Example: 1,000 per workflow type) through the new code and fails the build on any non-determinism error.

7.5 Retries, timeouts and guarantees

TimeoutMeaningExample
Schedule to startMaximum time in the task queue before a worker picks it upDetects missing workers
Start to closeMaximum time for one attemptExample: 30 s for a payment call
Schedule to closeMaximum total time including retriesExample: 1 hour
HeartbeatMaximum gap between heartbeats for long activitiesExample: 20 s

Guarantees:

  • Workflow state transitions are exactly once with respect to the history: a command is recorded once, and replay never repeats a recorded event.
  • Activities are at least once: a worker can crash after the side effect and before reporting completion. Activities must be idempotent; pass the workflow ID and activity ID as an idempotency key to external APIs.
  • Failures that should not be retried (validation errors) are marked non-retryable by the activity so the workflow can compensate at once.

How real systems do it (paraphrased from Uber Engineering, "Conducting Better Business with Uber's Open Source Orchestration Tool, Cadence", November 2019, and the Temporal documentation on workflow executions; see 12.4). The Uber write-up describes Cadence as multi-tenant middleware that brings its own persistence, queues and timers. Requests enter through a front-end layer; a history service owns shards of workflow state; a matching service hands tasks to workers; the reported storage back end was Cassandra, with queues kept in the same store. Teams write activities and combine them into workflows, and workers can be stopped and restarted without losing progress. The Temporal documentation explains how an execution resumes by replaying its event history, why workflow code must produce the same commands on replay, and that a single execution's history is limited in size, so long-lived workflows start new runs with continue-as-new. Lesson for this design: the engine stores and schedules, user code runs elsewhere, and bounded histories are part of the contract.

7.6 Visibility and archival

Visibility records are written from transfer tasks, so search can lag the true state by seconds; screens that need exact status call DescribeWorkflow, which reads the history store. After the retention period, the archiver writes the compressed history to object storage and deletes it from the primary store; the UI reads archived histories on demand.

8. Scalability and performance

ConcernApproachLimit before redesign
History write ratePartitioned store, batched appends per workflow taskExample: store cluster write throughput
Hot workflow (many signals)Signals buffered and applied per task; cap signals per executionExample: tens of events per second per workflow
Hot task queuePartitions plus per-queue rate limitsExample: about 16 partitions per queue
Replay costSticky execution; bounded historiesHistory length cap
Shard countFixed at creationRebuild cluster or migrate namespaces to grow beyond
VisibilitySeparate index clusterIndex write rate

Latency budget for a short workflow task (target p99 50 ms dispatch):

StepBudget
Transfer queue pickup10 ms
Matching sync match to a waiting poller5 ms
Network to worker5 ms
Worker execution with cached state10 ms
Completion and history append15 ms
Headroom5 ms

9. Reliability, security and operations

9.1 Failure modes

ComponentFailureDetectionBlast radiusMitigationRTO
History hostCrashMembership ring changeIts shards (about 1.6% of workflows on 64 hosts) pauseShards move to other hosts; fencing stops stale writesExample: 30 s
History storePartition unavailableWrite errors per shardWorkflows in affected shardsStore replication; engine retries with backoffStore RTO
Matching hostCrashPoll errorsQueues on that hostPartitions reassigned; backlog persistedExample: 30 s
WorkersCrash or not deployedSchedule-to-start timeout, backlog ageThat team's workflowsTasks wait safely; alert the owning teamTeam RTO
Workflow codeNon-determinism after deployNon-determinism error rateExecutions of that typeReplay tests in CI; roll back worker build; reset executionsExample: 15 min
NamespaceRunaway startsPer-namespace rateOther tenantsPer-namespace start and dispatch rate limitsExample: immediate
RegionFull outageProbesAll workflows in region[Single region / async replication of namespaces with failover][RTO]
[Component][Failure][Signal][Scope][Mitigation][RTO]

9.2 Security

ThreatControl
One team reading another's workflow dataNamespace isolation; authorisation on every API call
Sensitive data in history (permanent and replicated)Payload codec that encrypts payloads client-side with team keys; engine stores ciphertext
Malicious signal or startAuthenticated clients; signal schemas validated in workflow code
Worker impersonationMutual TLS between workers and frontend; per-namespace credentials
Retention of personal dataRetention per namespace; archive encryption; deletion process for data-subject requests
[Threat][Control]

9.3 Observability

SignalSourceAlert threshold
Task queue backlog ageMatchingExample: above 60 s for 5 min (team alert)
Schedule-to-start latencyMatchingExample: p99 above 1 s
Timer lagHistory timer queueExample: p99 above 1 s
Shard movement rateMembershipMore than [n] per hour
Non-determinism errorsWorkersAny after a deploy
Workflows stuck open beyond expected durationVisibilityPer type, team-defined

9.4 Cost estimate

ItemUnit costQuantityMonthly cost
History, matching and frontend hosts[USD per instance-month]Example: 64 + 16 + 8[USD]
History store[USD per TB-month]Example: about 181 TB replicated[USD]
Search index[USD per node-month][Nodes][USD]
Archive storage[USD per TB-month][TB per year][USD]
Total[USD]

10. Trade-offs and alternatives

DecisionOptionsChosenWhyWhat we give up
Programming modelDeclarative DSL (state-machine JSON or YAML); code with replayCode with replayReal language, tests, refactoringDeterminism rules to learn
Build or adoptBuild; adopt open-source engine; managed service[Decide; default adopt]Years of edge cases already solvedLess control over internals
State storageRelational; wide-column; distributed SQL[Decide]Write rate and per-shard transactionsOperational expertise needed
ShardingFixed shards; dynamic placementFixed shardsSimple ownership and fencingShard count cannot grow in place
Activity guaranteeAt most once; at least onceAt least onceNo silent lossActivities must be idempotent
What changes at 10x50,000 starts/s, 1 million events/sMultiple clusters with namespaces spread across them, larger history store, aggressive payload offloadHistory store write rate binds firstCross-cluster routing layer
What changes at 0.1x500 starts/sSingle small cluster or managed service; a relational store is enoughTeam cost dominatesLess headroom to grow

11. Delivery plan and risks

11.1 Milestones

MilestoneScopeExit criterionTarget date
M1Engine cluster, one pilot workflow in shadow modePilot outcomes match existing system for 14 daysYYYY-MM-DD
M2SDK guidance, replay tests in CI, versioning rulesTwo teams ship workflows with replay testsYYYY-MM-DD
M3Visibility, archival, per-namespace limitsGame day: history host loss and worker outageYYYY-MM-DD
M4Order fulfilment migratedStuck-order rate below [target]YYYY-MM-DD

11.2 Rollout and rollback

[Example: Migrate one process at a time. New orders start in the engine behind a flag; orders already in flight finish on the old path. Rollback stops new starts in the engine; running executions continue to completion.]

11.3 Risks

IDRiskLikelihoodImpactMitigationOwner
R-01Example: Teams write non-deterministic codeHighHighSDK lint rules, replay tests, training[@name]
R-02Example: Activities not idempotent cause duplicate chargesMediumHighIdempotency key convention; review checklist[@name]
R-03Example: Shard count too small for growthLowHigh4,096 shards; capacity review yearly[@name]
R-04Example: Engine becomes a dependency for every team without an on-call modelMediumMediumPlatform on-call, SLOs per namespace[@name]
[R-nn][Risk][L / M / H][L / M / H][Mitigation][@name]

12. Appendices

12.1 Open questions

IDQuestionOwnerDue
OQ-01Example: Do we need multi-region replication of namespaces in year one?[@name]YYYY-MM-DD
OQ-02Example: Which workflow types need history retention beyond 7 days in the primary store?[@name]YYYY-MM-DD
[OQ-nn][Question][@name]YYYY-MM-DD

12.2 Traceability

RequirementDesign sectionVerification
FR-027.5Activity retry tests with injected failures
FR-03, NFR-053.3, 7.2Timer lag under 72 million pending timers (scaled test)
FR-077.4Replay test in CI on production histories
NFR-017.2, 9.1Kill history host mid-transaction; verify no lost events
NFR-067.3, 9.1Noisy-namespace load test

12.3 Glossary

TermMeaning
Workflow executionOne run of a workflow type, identified by workflow ID and run ID
Event historyAppend-only list of events that records everything an execution did
ReplayRe-running workflow code against its history to rebuild state
ActivityA unit of side-effecting work run by a worker, with retries and timeouts
Task queueNamed queue from which workers poll workflow or activity tasks
ShardFixed partition of executions owned by one history host at a time
Continue as newEnding a run and starting a fresh run with carried-over state to bound history
Transfer queuePer-shard outbox of tasks written in the same transaction as events

12.4 References

ReferenceUse
Uber Engineering blog, "Conducting Better Business with Uber's Open Source Orchestration Tool, Cadence" (12 November 2019)Inspiration for the box in 7.5 (paraphrased)
Temporal documentation, "Workflow Execution" and "Workflow Execution limits" (docs.temporal.io)Event history, replay, continue-as-new, history limits used as reference for 7.1
Cadence project (cadenceworkflow.io); Uber Engineering blog, "Cadence Workflow Joins the Cloud Native Computing Foundation" (2025)Background on the open-source engine
Job Scheduler System Design Template (system-design/design-job-scheduler)Scheduling independent jobs
Message Queue System Design Template (system-design/design-message-queue)Queue semantics for activities that publish events
Event Sourcing and CQRS Template (architecture/event-sourcing-cqrs)Related pattern of event-sourced state
Payment Ledger System Design Template (system-design/design-payment-ledger)Idempotency for payment activities

Standard and licence note

Based on common industry practice for durable execution engines; no formal standard governs this class of system. The Uber and Temporal material is used as inspiration only and is paraphrased, not copied; product-specific limits change between releases, so check the current documentation of any engine you adopt. All numbers are illustrative examples. Original text written for this collection. Template licence: MIT.

関連テンプレート