Skip to main content

Run a Worker - Go SDK

View Markdown

This page covers long-lived Workers that you host and run as persistent processes. For Workers that run on serverless compute like AWS Lambda, see Serverless Workers.

Create and run a Worker

Create a Worker by calling worker.New() and passing:

  1. A Temporal Client.
  2. The name of the Task Queue to poll.
  3. A worker.Options struct (can be empty for defaults).

Register your Workflow and Activity types, then call Run() to start polling. The Worker blocks while it polls, so run it in a separate terminal from your starter code.

helloworld/worker/main.go

package main

import (
"log"

"go.temporal.io/sdk/client"
"go.temporal.io/sdk/contrib/envconfig"
"go.temporal.io/sdk/worker"

"github.com/temporalio/samples-go/helloworld"
)

func main() {
// The client and worker are heavyweight objects that should be created once per process.
c, err := client.Dial(envconfig.MustLoadDefaultClientOptions())
if err != nil {
log.Fatalln("Unable to create client", err)
}
defer c.Close()

w := worker.New(c, "hello-world", worker.Options{})

w.RegisterWorkflow(helloworld.Workflow)
w.RegisterActivity(helloworld.Activity)

err = w.Run(worker.InterruptCh())
if err != nil {
log.Fatalln("Unable to start worker", err)
}
}

Run() accepts an interrupt channel so the Worker shuts down on SIGINT or SIGTERM. You can also call Start() and Stop() separately for more control over the lifecycle.

tip

If you have gow installed, the Worker automatically reloads when you update the file:

go install github.com/mitranim/gow@latest
gow run worker/main.go

Register Workflows and Activities

All Workers listening to the same Task Queue must be registered to handle the same Workflow Types and Activity Types. If a Worker polls a Task for a type it does not know about, the Task fails. The Workflow Execution itself does not fail.

Use RegisterWorkflow() and RegisterActivity() to register types. To register an Activity struct with multiple methods, pass the struct. The Worker gets access to all exported methods.

w.RegisterWorkflow(WorkflowA)
w.RegisterWorkflow(WorkflowB)
w.RegisterActivity(&MyActivities{})

To customize the registered name or other options, use RegisterWorkflowWithOptions() or RegisterActivityWithOptions(). See workflow.RegisterOptions and activity.RegisterOptions.

Connect to Temporal Cloud

To run a Worker against Temporal Cloud, configure the Client connection with your Namespace address and authentication credentials. See Connect to Temporal Cloud for setup instructions.

Configure Worker options

Pass a worker.Options struct to worker.New() to configure concurrency limits, pollers, timeouts, and other Worker behavior. An empty struct uses defaults that work for most cases.

To tune these values against real load, see Worker performance and the Worker tuning reference.

Run a versioned Worker

Set a Worker Deployment Version and enable versioning in worker.Options, then set a versioning behavior on each Workflow.

features/snippets/worker/worker.go

w := worker.New(c, "my-task-queue", worker.Options{
DeploymentOptions: worker.DeploymentOptions{
UseVersioning: true,
Version: worker.WorkerDeploymentVersion{
DeploymentName: "my-app",
BuildID: "1.0",
},
},
})

w.RegisterWorkflowWithOptions(HelloWorkflow, workflow.RegisterOptions{
VersioningBehavior: workflow.VersioningBehaviorPinned,
})

See Worker Versioning for the available versioning behaviors and how new versions roll out.

Shut down a Worker

A Worker started with Run(worker.InterruptCh()) shuts down when the process receives SIGINT or SIGTERM. It stops polling for new Tasks and waits for in-flight Tasks to finish, up to the WorkerStopTimeout set in worker.Options.

See Worker shutdown for what happens to in-flight Workflow Tasks and Activities.