# Standalone Activities Feature Guide

> For the complete documentation index, see [llms.txt](https://docs.temporal.io/llms.txt).
> Any documentation page is available as raw Markdown by appending `.md` to its URL.

> Execute Activities independently without a Workflow using the Temporal Java SDK.

> **Public Preview**

[Standalone Activities](/standalone-activity) 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 using `ActivityClient`.

The way you write the Activity and register it with a Worker is identical to [Workflow
Activities](/develop/java/activities/basics). 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](/develop/java/activities/standalone-activities-quickstart).
>

This page covers the following:

- [Start a Standalone Activity without waiting for the result](#start-activity)
- [Get a handle to an existing Standalone Activity](#get-activity-handle)
- [Wait for the result of a Standalone Activity](#get-activity-result)
- [List Standalone Activities](#list-activities)
- [Count Standalone Activities](#count-activities)
- [Run Standalone Activities with Temporal Cloud](#run-standalone-activities-temporal-cloud)

> **📝 Note:**
>
> This documentation uses source code from the
> [standaloneactivities](https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/standaloneactivities)
> sample.
>

## 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
[`ActivityClient.start()`](https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/client/ActivityClient.html)
to start a Standalone Activity and get a handle without waiting for the result:

[StartActivity.java](https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/standaloneactivities/StartActivity.java)

```java
ActivityHandle<String> handle =
    client.start(
        GreetingActivities.class,
        GreetingActivities::composeGreeting,
        options,
        "Hello",
        "World");
System.out.println("Started activity ID: " + ACTIVITY_ID);

// Wait for the result later
String result = handle.getResult();
System.out.println("Activity result: " + result);
```

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

```bash
./gradlew -q execute -PmainClass=io.temporal.samples.standaloneactivities.StartActivity
```

Or use the Temporal CLI:

```bash
./temporal activity start \
  --type ComposeGreeting \
  --activity-id standalone-activity-id \
  --task-queue standalone-activity-task-queue \
  --start-to-close-timeout 10s \
  --input '"Hello"' \
  --input '"World"'
```

## Get a handle to an existing Standalone Activity 

Use `client.getHandle()` to create a typed handle to a previously started Standalone Activity:

```java
ActivityHandle<String> handle =
    client.getHandle("standalone-activity-id", null, String.class);
```

Pass `null` as the run ID to target the latest run of the given activity ID. You can then 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()` is the same as calling `client.start()` to durably
enqueue the Standalone Activity, and then calling `handle.getResult()` to block until the Activity
completes and return the result:

```java
String result = handle.getResult();
```

To wait asynchronously without blocking the calling thread, use `handle.getResultAsync()`, which
returns a `CompletableFuture<R>`:

```java
CompletableFuture<String> future = handle.getResultAsync();
```

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

```bash
./temporal activity result --activity-id standalone-activity-id
```

## List Standalone Activities 

Use
[`client.listExecutions()`](https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/client/ActivityClient.html)
to list Standalone Activity Executions that match a [List Filter](/list-filter) query. The result is
a `Stream<ActivityExecutionMetadata>` that fetches pages from the server on demand as the stream is
consumed.

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

[ListActivities.java](https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/standaloneactivities/ListActivities.java)

```java
client
    .listExecutions("TaskQueue = '" + TASK_QUEUE + "'")
    .forEach(
        info ->
            System.out.printf(
                "ActivityID: %s, Type: %s, Status: %s%n",
                info.getActivityId(), info.getActivityType(), info.getStatus()));
```

Run it:

```bash
./gradlew -q execute -PmainClass=io.temporal.samples.standaloneactivities.ListActivities
```

Or use the Temporal CLI:

```bash
./temporal activity list
```

The query parameter accepts the same [List Filter](/list-filter) syntax used for [Workflow
Visibility](/visibility). For example, `ActivityType = 'composeGreeting' AND Status = 'Running'`.

## Count Standalone Activities 

Use
[`client.countExecutions()`](https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/client/ActivityClient.html)
to count Standalone Activity Executions that match a [List Filter](/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.

[CountActivities.java](https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/standaloneactivities/CountActivities.java)

```java
ActivityExecutionCount resp = client.countExecutions("TaskQueue = '" + TASK_QUEUE + "'");
System.out.println("Total activities: " + resp.getCount());
resp.getGroups()
    .forEach(
        group ->
            System.out.println("Group " + group.getGroupValues() + ": " + group.getCount()));
```

Run it:

```bash
./gradlew -q execute -PmainClass=io.temporal.samples.standaloneactivities.CountActivities
```

Or use the Temporal CLI:

```bash
./temporal activity count
```

## Run Standalone Activities with Temporal Cloud 

The Worker and Client code in the [Standalone Activities Quickstart](/develop/java/activities/standalone-activities-quickstart)
use `ClientConfigProfile.load()`, so the same code works against Temporal Cloud — 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](/develop/java/client/temporal-client#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](/develop/java/activities/standalone-activities-quickstart).
