Skip to main content

Standalone Activities Feature Guide

View Markdown

Standalone Activities are Activities that run independently, without being orchestrated by a Workflow. Instead of starting an Activity from within a Workflow Definition, you start a Standalone Activity directly from a Temporal Client.

The way you write the Activity and register it with a Worker is identical to Workflow Activities. The only difference is that you execute a Standalone Activity directly from your Temporal Client.

tip

New to Standalone Activities? Start with the Standalone Activities Quickstart.

This page covers the following:

info

This documentation uses source code from the hello_standalone_activity sample.

Prerequisites​

Standalone Activities require:

  • Python 3.10+
  • Temporal Python SDK v1.33.0 or higher
  • Temporal CLI v1.9.1 or higher

The Standalone Activities Quickstart walks through installing these.

Start a Standalone Activity without waiting for the result​

Starting a Standalone Activity means sending a request to the Temporal Server to durably enqueue your Activity job, without waiting for it to be executed by your Worker.

Use client.start_activity() to start your Standalone Activity and get a handle:

activity_handle = await client.start_activity(
compose_greeting,
args=[ComposeGreetingInput("Hello", "World")],
id="my-standalone-activity-id",
task_queue="my-standalone-activity-task-queue",
start_to_close_timeout=timedelta(seconds=10),
)

With the Temporal Server and Worker running, open a new terminal in the samples-python directory and run:

uv run hello_standalone_activity/start_activity.py

Or use the Temporal CLI:

temporal activity start \
--type compose_greeting \
--activity-id my-standalone-activity-id \
--task-queue my-standalone-activity-task-queue \
--start-to-close-timeout 10s \
--input '{"greeting": "Hello", "name": "World"}'

Get a handle to an existing Standalone Activity​

You can also use client.get_activity_handle() to create a handle to a previously started Standalone Activity:

activity_handle = client.get_activity_handle(
activity_id="my-standalone-activity-id",
run_id="the-run-id",
)

You can now use the handle to wait for the result, describe, cancel, or terminate the Activity.

Wait for the result of a Standalone Activity​

Under the hood, calling client.execute_activity() is the same as calling client.start_activity() to durably enqueue the Standalone Activity, and then calling await activity_handle.result() to wait for the activity to be executed and fetch the result:

activity_result = await activity_handle.result()

Or use the Temporal CLI to wait for a result by Activity ID:

temporal activity result --activity-id my-standalone-activity-id

List Standalone Activities​

Use client.list_activities() to list Standalone Activity Executions that match a List Filter query. The result is an async iterator that yields ActivityExecution entries.

These APIs return only Standalone Activity Executions. Activities running inside Workflows are not included.

hello_standalone_activity/list_activities.py

import asyncio

from temporalio.client import Client
from temporalio.envconfig import ClientConfig


async def my_application():
connect_config = ClientConfig.load_client_connect_config()
connect_config.setdefault("target_host", "localhost:7233")
client = await Client.connect(**connect_config)

activities = client.list_activities(
query="TaskQueue = 'my-standalone-activity-task-queue'",
)

async for info in activities:
print(
f"ActivityID: {info.activity_id}, Type: {info.activity_type}, Status: {info.status}"
)


if __name__ == "__main__":
asyncio.run(my_application())

Run it:

uv run hello_standalone_activity/list_activities.py

Or use the Temporal CLI:

temporal activity list

The query parameter accepts the same List Filter syntax used for Workflow Visibility. For example, "ActivityType = 'MyActivity' AND ExecutionStatus = 'Running'".

Count Standalone Activities​

Use client.count_activities() to count Standalone Activity Executions that match a List Filter query. This returns the total count of executions (running, completed, failed, etc.) - not the number of queued tasks. It works the same way as counting Workflow Executions.

hello_standalone_activity/count_activities.py

import asyncio

from temporalio.client import Client
from temporalio.envconfig import ClientConfig


async def my_application():
connect_config = ClientConfig.load_client_connect_config()
connect_config.setdefault("target_host", "localhost:7233")
client = await Client.connect(**connect_config)

resp = await client.count_activities(
query="TaskQueue = 'my-standalone-activity-task-queue'",
)

print("Total activities:", resp.count)

for group in resp.groups:
print(f"Group {group.group_values}: {group.count}")


if __name__ == "__main__":
asyncio.run(my_application())

Run it:

uv run hello_standalone_activity/count_activities.py

Or use the Temporal CLI:

temporal activity count

Run Standalone Activities with Temporal Cloud​

The code samples on this page use ClientConfig.load_client_connect_config(), so the same code works against Temporal Cloud - just configure the connection via environment variables or a TOML profile. No code changes are needed.

For a step-by-step guide on connecting to Temporal Cloud, including Namespace creation, certificate generation, and authentication setup in the Cloud UI, see Connect to Temporal Cloud.

Connect with mTLS​

Set these environment variables with values from your Temporal Cloud Namespace settings:

export TEMPORAL_ADDRESS=<your-namespace>.<your-account-id>.tmprl.cloud:7233
export TEMPORAL_NAMESPACE=<your-namespace>.<your-account-id>
export TEMPORAL_TLS_CLIENT_CERT_PATH='path/to/your/client.pem'
export TEMPORAL_TLS_CLIENT_KEY_PATH='path/to/your/client.key'

Connect with an API key​

Set these environment variables with values from your Temporal Cloud API key settings:

export TEMPORAL_ADDRESS=<your-namespace>.<your-account-id>.tmprl.cloud:7233
export TEMPORAL_NAMESPACE=<your-namespace>.<your-account-id>
export TEMPORAL_API_KEY=<your-api-key>

Then run the Worker and starter code as shown in the Standalone Activities Quickstart.