new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Temporal · Concepts · all subjects

activities/core-concepts

44 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Activity idempotency recommendation

Activities should be idempotent. This recommendation helps ensure consistent results when activities are retried due to failures.

Common activity use cases

Activities encompass small units of work including: single write operations like updating user information or submitting credit card payments; batches of similar writes like creating multiple orders or sending multiple messages; one or more read operations followed by a write operation like checking product status before updating order status; and reads that should be memoized like LLM calls, large downloads, or slow-polling reads.

Activity definition and purpose

An Activity is a normal function or method that executes a single, well-defined action (either short or long running), such as calling another service, transcoding a media file, or sending an email message. Activity code can be non-deterministic.

Idempotency definition for Activities

Idempotence means that performing an operation multiple times has the same result as performing it once. In the context of Temporal, Activities should be designed to be safely executed multiple times without causing unexpected or undesired side effects. An Activity is idempotent if multiple Activity Task Executions do not change the state of the system beyond the first Activity Task Execution.

Why Activities must be idempotent

Activities may be retried and can be executed more than once. A non-idempotent Activity could adversely affect the state of the system. Completed Activities will not re-execute as part of a Workflow Replay, but if an Activity fails to report to the server at all, it will be retried. An edge case can occur where a Worker crashes just before notifying the Temporal Service of successful Activity completion, causing the Activity to be retried despite successful execution. Designing Activities for idempotence improves reusability and reliability, especially if you have a Global Namespace.

Idempotency key pattern for Activity idempotence

Idempotency can be achieved through the use of unique identifiers known as idempotency keys, which are used to detect duplicate requests. These are enforced by the service being called from the Activity, not by the Activity itself. In Temporal, you can use a combination of the Workflow Run ID and the Activity ID as an idempotency key, since this is guaranteed to be consistent across retry attempts but unique among Workflow Executions. Most payment processors allow including an idempotency key with requests to prevent duplicate charges.

Activity granularity and idempotency trade-off

Activities are an atomic unit of execution within Temporal and are invoked as a whole—they either complete successfully or not. To maintain idempotency and enable retrying only the failed step, Activities should be designed to be granular. For example, if an Activity has three steps (database lookup, microservice call, filesystem write) and the third step fails, redesigning into three separate Activities allows only the third to retry. However, this must be balanced against the potential for a larger Event History with more Activity Executions.

Activity constraints

Activity Definitions are executed as normal functions. In the event of failure, the function begins at its initial state when retried, except when Activity Heartbeats are established. Therefore, an Activity Definition has no restrictions on the code it contains.

Activity parameters requirements

An Activity Definition can support as many parameters as needed. All values passed through these parameters are recorded in the Event History of the Workflow Execution, and return values are also captured in the Event History. Activity Definitions must contain: Context (an optional parameter that provides Activity context within multiple APIs), Heartbeat (a notification from the Worker to the Temporal Service that the Activity Execution is progressing, with Cancelations allowed only if the Activity Definition permits Heartbeating), and Timeouts (intervals that control the execution and retrying of Activity Task Executions).

Activity Type definition

An Activity Type is the mapping of a name to an Activity Definition. Activity Types are scoped through Task Queues.

Best practices for defining Activities

Activity arguments and return values should be serializable. Activities that perform writes should be idempotent. Activities have timeouts and retry policies; operations should either complete within a few minutes or support the ability to heartbeat or poll for a result so it will be clear to the Workflow when the Activity is still making progress. Specify at least one timeout, typically the start_to_close timeout. Shorter timeouts allow Temporal to retry faster upon failure.

Activity naming and reference

Activity Definitions are named and referenced in code by their Activity Type.

Activity Definition purpose

An Activity Definition is the code that defines the constraints of an Activity Task Execution. Activities encapsulate business logic that is prone to failure, allowing for automatic retries when issues occur.

Activity Definition examples across SDKs

Go: func YourSimpleActivity(ctx context.Context) error { return nil } Java interface: @ActivityInterface public interface GreetingActivities { @ActivityMethod String composeGreeting(String greeting, String language); } Java implementation: static class GreetingActivitiesImpl implements GreetingActivities { @Override public String composeGreeting(String greeting, String name) { return greeting + " " + name + "!"; } } PHP interface: #[ActivityInterface] interface GreetingActivities { public function composeGreeting(string $greeting, string $name): string; } PHP implementation: class GreetingActivitiesImpl implements GreetingActivities { public function composeGreeting(string $greeting, string $name): string { return $greeting . ' ' . $name; } } Python: @activity.defn(name="your_activity") async def your_activity(input: YourParams) -> str: return f"{input.greeting}, {input.name}!" TypeScript: export async function greet(name: string): Promise<string> { return `Hello, ${name}!`; } .NET: [Activity] public string MyActivity(MyActivityParams input) => $"{input.Greeting}, {input.Name}!"; Rust: #[activity] pub async fn greet(_ctx: ActivityContext, name: String) -> Result<String, ActivityError> { Ok(format!("Hello, {}!", name)) }

Local Activity latency and Event history benefits

Because a Local Activity avoids the round trip through the Temporal Service, it has significantly lower latency and produces fewer Event History entries than a regular Activity.

Local Activity definition and execution location

A Local Activity is an Activity Execution that executes in the same Worker process as the Workflow Execution that schedules it. Unlike a regular Activity, a Local Activity never enters an Activity Task Queue. Instead, the Workflow Worker executes it directly in an in-process queue.

Local Activity use case requirements

Consider using a Local Activity only when the operation is short-lived (completes in a few seconds, including retries), can execute in the same binary as the Workflow, does not require routing to a specific Worker or Task Queue, does not require global rate limiting, and is idempotent.

When to use Local Activities vs regular Activities

Use a Local Activity when execution completes in a few seconds, retries are expected to be short, the operation is idempotent, low latency is more important than full durability, and routing, rate limiting, and separate Activity Workers are unnecessary. Use a regular Activity when interacting with external systems, execution may take longer than a few seconds, retries may span minutes or hours, Activity heartbeating is required, or strong durability guarantees are important.

Good use cases for Local Activities

Good use cases for Local Activities include lightweight data transformations, small computations, reading from an in-memory cache, fast local filesystem operations, and high-throughput Workflows with many very short-lived operations.

Good use cases for regular Activities

Use regular Activities for network requests, database operations, external API calls, long-running work, operations requiring durable retries, and operations that benefit from Task Queue routing or rate limiting.

Activity vs Local Activity feature comparison table

Feature comparison between Activity and Local Activity: Execution: Activity executes in Activity Worker; Local Activity executes in Workflow Worker Task Queue: Activity uses Task Queue; Local Activity does not use Task Queue Service round trip: Activity requires Service round trip; Local Activity does not require Service round trip Latency: Activity has higher latency; Local Activity has lower latency Event history: Activity is fully recorded; Local Activity records MarkerRecorded on completion Heartbeating: Activity uses Activity heartbeats; Local Activity uses Workflow Task heartbeating Retry durability: Activity is durable; Local Activity is at-least-once until marker is recorded Signal responsiveness: Activity is unaffected by signal; Local Activity is delayed while the Workflow Task executes Best for: Activity is best for general-purpose work; Local Activity is best for short, high-throughput operations

Recommendation for Local Activity usage

Use Local Activities only when your use case requires the performance optimization they provide, such as high-throughput Workflows with many very short-lived operations. For most business logic, regular Activities are the better choice. For most production workloads, regular Activities remain the recommended default.

Activity Operations overview and availability

Activity Operations are deliberate actions performed on a specific Activity Execution, distinct from automatic lifecycle behaviors like retries and timeouts. They can be performed through CLI, UI, or gRPC API. Activity Operations are in Public Preview as of Server v1.28.0+ for Pause, Unpause, and Reset; self-hosted UI requires v2.47.0+. Activity Operations are not available as SDK client methods and are designed for CLI, UI, and gRPC API use, not for programmatic use in Workflow or Activity code. Activity Operations don't apply to Local Activities or Standalone Activities.

Standalone Activity vs Workflow execution

Standalone Activities execute a single Activity reliably as a top-level primitive. Workflows orchestrate multiple Activity steps. Using a Standalone Activity instead of a Workflow for a single Activity results in fewer Billable Actions in Temporal Cloud and lower latency due to fewer Worker round-trips.

Standalone Activity Function code reuse

The same Activity Function can be executed as a Standalone Activity and as a Workflow Activity with no code changes. Activity Functions are written the same way for both execution modes.

Standalone Activity key features

Standalone Activities support: execution as a top-level primitive without Workflow overhead; native async job processing model (schedule -> dispatch -> process -> result); no head-of-line blocking; arbitrary length jobs with heartbeats for liveness and progress checkpointing; at-least-once execution by default with native retry policy and timeouts; at-most-once execution if retry max attempts is 1; addressable Activity ID/Run ID with get result, cancel, and terminate operations; deduplication with conflict policy (USE_EXISTING) and reuse policy (REJECT_DUPLICATES); separate ID space from Workflows; priority and fairness with multi-tenant fairness and weighted priority tiers; visibility to list Activity Executions with status, retry count, and last error; manual completion by ID or token; activity metrics for success, failure, timeout, and cancel; dual use as Activities within a Workflow or standalone.

Standalone Activity observability

All existing Activity metrics apply to Standalone Activities, including counts for scheduled, started, completed, failed, timed out, and canceled activities. Use List Filters to query Standalone Activity Executions by type, status, task queue, and other attributes using the SDK or the temporal activity list CLI command. CountActivities returns the total number of Standalone Activity Executions matching a filter (running, completed, failed, etc.), not the number of queued tasks.

Standalone Activity Public Preview limitations

The Public Preview of Standalone Activities does not support: pause, reset, and update options (scheduled for GA); TerminateExisting conflict policy / TerminateIfRunning reuse policy.

Standalone Activity version requirements

Standalone Activities require Temporal CLI v1.7.0 or higher and Temporal Server v1.31.0 or higher. Available in Temporal Cloud as a Public Preview feature and in Temporal Server v1.31.0 or higher (included in Temporal CLI v1.7.0 or higher). The Temporal Dev Server has Standalone Activities enabled by default for local testing.

Standalone Activity supported languages

Standalone Activities are available in Go, Python, Java, .NET, TypeScript, and Ruby SDKs.

Standalone Activity CLI commands

The temporal activity subcommand supports Standalone Activities with commands: start, execute, result, list, count, describe, cancel, and terminate.

Standalone Activity definition

A Standalone Activity is a top-level Activity Execution started directly by a Client, without using a Workflow.

Dynamic Activity definition and purpose in .NET

A Dynamic Activity in Temporal is an Activity that is invoked dynamically at runtime if no other Activity with the same name is registered. An Activity can be made dynamic by setting Dynamic as true on the [Activity] attribute. Only one Dynamic Activity can be present on a Worker.

Dynamic Activity parameter requirements in .NET

The Activity Definition for a Dynamic Activity must accept a single argument of type Temporalio.Converters.IRawValue[]. The PayloadConverter property on the ActivityExecutionContext is used to convert an IRawValue object to the desired type using extension methods in the Temporalio.Converters namespace.

Dynamic Activity definition and invocation

A Dynamic Activity in Temporal is an Activity that is invoked dynamically at runtime if no other Activity with the same name is registered. Only one Dynamic Activity can be present on a Worker. A Dynamic Activity must be registered with the Worker before it can be invoked.

Dynamic Activity function signature

The Activity Definition for a Dynamic Activity must accept a single argument of type converter.EncodedValues and return a value and an error. The EncodedValues can be decoded to extract the actual arguments passed at runtime.

Dynamic Activity example in Go

func DynamicActivity(ctx context.Context, args converter.EncodedValues) (string, error) { var arg1, arg2 string err := args.Get(&arg1, &arg2) if err != nil { return "", fmt.Errorf("failed to decode arguments: %w", err) } info := activity.GetInfo(ctx) result := fmt.Sprintf("%s - %s - %s", info.WorkflowType.Name, arg1, arg2) return result, nil } This example demonstrates a Dynamic Activity that decodes two string arguments from converter.EncodedValues, retrieves the workflow type name using activity.GetInfo(), and returns a formatted result string.

Activity Definition in .NET SDK

An Activity in the Temporal .NET SDK is a method decorated with the [Activity] attribute. The same Activity can be executed both as a Standalone Activity and as a Workflow Activity. The core purpose of an Activity Definition is to define executable business logic that can be invoked either from within a Workflow or as a Standalone Activity independent of orchestration.

Activity definition example in Go

Example Activity definition shared by both Worker and starter: ```go package helloworld import ( "context" "go.temporal.io/sdk/activity" ) func Activity(ctx context.Context, name string) (string, error) { logger := activity.GetLogger(ctx) logger.Info("Activity", "name", name) return "Hello " + name + "!", nil } ``` This shows a basic Activity that takes a name parameter and returns a greeting string.

Activity basic purpose

An Activity is a normal method execution intended to execute a single, well-defined action that is either short or long-running, such as querying a database, calling a third-party API, or transcoding a media file. An Activity can interact with the world outside the Temporal Platform or use a Temporal Client to interact with a Temporal Service.

Workflow orchestrates Activity execution

One of the primary things that Workflows do is orchestrate the execution of Activities. For a Workflow to execute an Activity, the Activity Definition must be defined.

Activity definition with [Activity] attribute

An Activity Definition is created by applying the [Activity] attribute from the Temporalio.Activities namespace to a method. To register with a custom name, use an attribute parameter like [Activity("your-activity")]. Otherwise, the activity name is the unqualified method name without an "Async" suffix if the method is async.

Activity parameter size limits

A single Activity argument is limited to a maximum size of 2 MB. The total size of a gRPC message, which includes all arguments, is limited to a maximum of 4 MB.

Activity definition and role

Activities in Temporal are individual units of work that often represent non-deterministic parts of the code logic, such as querying a database or calling an external service. By default, if an Activity attempts to communicate with another system and encounters a transient failure like a network issue, Temporal ensures the Activity is tried again automatically. Temporal enables developers to control timeouts, Retry Policy, Heartbeat monitoring, and asynchronous completion.

Give your agent this brain