Quickstart
Standalone Activities are Activity Executions that run independently, without being orchestrated by a Workflow. Instead
of starting an Activity from within a Workflow Definition using workflow.ExecuteActivity(), you start a Standalone
Activity directly from a Temporal Client using client.ExecuteActivity().
The Activity definition and Worker registration are identical to regular Activities, and only the execution path differs.
This documentation uses source code from the standalone-activity/helloworld.
Get started with Standalone Activities
Prerequisites:
-
Go 1.22+
-
Temporal Go SDK (v1.41.0 or higher)
-
Temporal CLI v1.7.0 or higher. Install with Homebrew, or see the Temporal CLI install guide for other platforms. Verify the installation with
temporal --version.
Start the Temporal development server with temporal server start-dev.
This command automatically starts the Temporal development server with the Web UI, and creates the default Namespace.
It uses an in-memory database, so do not use it for real use cases.
The Temporal Server should now be available for client connections on localhost:7233, and the
Temporal Web UI should now be accessible at http://localhost:8233.
brew install temporal
temporal --version
temporal server start-dev
Clone the sample
Clone the samples-go repository to follow along:
git clone https://github.com/temporalio/samples-go.git
cd samples-go
The sample project is structured as follows:
standalone-activity/helloworld/
├── activity.go
├── worker/
│ └── main.go
└── starter/
└── main.go
Define your Activity
Define your Activity in a shared file so that both the Worker and starter can reference it.
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
}
Run a Worker with the Activity registered
Running a Worker for Standalone Activities is the same as running a Worker for Workflow-driven Activities — you create a
Worker, register the Activity, and call Run(). The Worker doesn't need to know whether the Activity will be invoked
from a Workflow or as a Standalone Activity.
See How to develop a Worker in Go for more details on Worker setup and configuration options.
standalone-activity/helloworld/worker/main.go
Open a new terminal, navigate to the samples-go directory, and run the Worker.
Leave this terminal running - the Worker needs to stay up to process activities.
package main
import (
"github.com/temporalio/samples-go/standalone-activity/helloworld"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/contrib/envconfig"
"go.temporal.io/sdk/worker"
"log"
)
func main() {
c, err := client.Dial(envconfig.MustLoadDefaultClientOptions())
if err != nil {
log.Fatalln("Unable to create client", err)
}
defer c.Close()
w := worker.New(c, "standalone-activity-helloworld", worker.Options{})
w.RegisterActivity(helloworld.Activity)
err = w.Run(worker.InterruptCh())
if err != nil {
log.Fatalln("Unable to start worker", err)
}
}
go run standalone-activity/helloworld/worker/main.go
Execute a Standalone Activity
Use client.ExecuteActivity() to start a Standalone Activity
Execution. This is called from application code (for example, a starter program), not from inside a Workflow Definition.
ExecuteActivity returns an ActivityHandle that you
can use to get the result, describe, cancel, or terminate the Activity.
The following starter program demonstrates how to execute a Standalone Activity, get its result, list activities, and count activities:
Create standalone-activity/helloworld/starter/main.go.
You can pass the Activity as either a function reference or a string Activity type name:
handle, err := c.ExecuteActivity(ctx, options, helloworld.Activity, "arg1")
// Using a string type name
handle, err := c.ExecuteActivity(ctx, options, "Activity", "arg1")
client.StartActivityOptions requires ID, TaskQueue, and at least one of ScheduleToCloseTimeout or
StartToCloseTimeout. See StartActivityOptions
in the API reference for the full set of options.
To run the starter:
- Make sure the Temporal Server is running (from the Get Started step above).
- Make sure the Worker is running (from the Run a Worker step above).
- Open a new terminal, navigate to the
samples-godirectory, and rungo run standalone-activity/helloworld/starter/main.go.
Or use the Temporal CLI to execute a Standalone Activity.
package main
import (
"context"
"github.com/temporalio/samples-go/standalone-activity/helloworld"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/contrib/envconfig"
"log"
"time"
)
func main() {
c, err := client.Dial(envconfig.MustLoadDefaultClientOptions())
if err != nil {
log.Fatalln("Unable to create client", err)
}
defer c.Close()
activityOptions := client.StartActivityOptions{
ID: "standalone_activity_helloworld_ActivityID",
TaskQueue: "standalone-activity-helloworld",
ScheduleToCloseTimeout: 10 * time.Second,
}
handle, err := c.ExecuteActivity(context.Background(), activityOptions, helloworld.Activity, "Temporal")
if err != nil {
log.Fatalln("Unable to execute activity", err)
}
log.Println("Started standalone activity", "ActivityID", handle.GetID(), "RunID", handle.GetRunID())
var result string
err = handle.Get(context.Background(), &result)
if err != nil {
log.Fatalln("Unable get standalone activity result", err)
}
log.Println("Activity result:", result)
resp, err := c.ListActivities(context.Background(), client.ListActivitiesOptions{
Query: "TaskQueue = 'standalone-activity-helloworld'",
})
if err != nil {
log.Fatalln("Unable to list activities", err)
}
log.Println("ListActivity results")
for info, err := range resp.Results {
if err != nil {
log.Fatalln("Error iterating activities", err)
}
log.Printf(" ActivityID: %s, Type: %s, Status: %v
",
info.ActivityID, info.ActivityType, info.Status)
}
resp1, err := c.CountActivities(context.Background(), client.CountActivitiesOptions{
Query: "TaskQueue = 'standalone-activity-helloworld'",
})
if err != nil {
log.Fatalln("Unable to count activities", err)
}
log.Println("Total activities:", resp1.Count)
}
go run standalone-activity/helloworld/starter/main.go
temporal activity execute \
--type Activity \
--activity-id standalone_activity_helloworld_ActivityID \
--task-queue standalone-activity-helloworld \
--schedule-to-close-timeout 10s \
--input '"Temporal"'
Run with Temporal Cloud
All code samples on this page use
envconfig.MustLoadDefaultClientOptions()
to configure the Temporal Client connection. It responds to environment
variables and TOML configuration
files, so the same code works against a local dev
server and Temporal Cloud without changes. See Run Standalone Activities with Temporal
Cloud in the Feature Guide
for mTLS and API key setup.
Next steps
- Standalone Activities Feature Guide: Get results, Activity handles, list and count Activities, and connect to Temporal Cloud.
- Activity basics: How to write and register Activities with the Go SDK.