Skip to main content

Serverless workers - Go SDK

The lambdaworker package lets you run a Temporal Worker on AWS Lambda without managing long-lived compute. Deploy your Worker code as a Lambda function, and Temporal Cloud invokes it when tasks arrive. Each invocation starts a Worker, polls for tasks until the Lambda deadline approaches, then gracefully drains and shuts down. You register Workflows and Activities the same way you would with a standard Worker.

For a full end-to-end deployment guide covering AWS IAM setup, compute configuration, and verification, see Deploy a serverless worker.

Lambda Worker setup

Use the RunWorker function to start a Lambda-based Worker. Pass a WorkerDeploymentVersion and a callback that registers your Workflows and Activities.

package main

import (
lambdaworker "go.temporal.io/sdk/contrib/aws/lambdaworker"
"go.temporal.io/sdk/worker"
"go.temporal.io/sdk/workflow"
)

func main() {
lambdaworker.RunWorker(worker.WorkerDeploymentVersion{
DeploymentName: "my-app",
BuildID: "build-1",
}, func(opts *lambdaworker.Options) error {
opts.TaskQueue = "my-task-queue"

opts.RegisterWorkflowWithOptions(MyWorkflow, workflow.RegisterOptions{
VersioningBehavior: workflow.VersioningBehaviorAutoUpgrade,
})
opts.RegisterActivity(MyActivity)

return nil
})
}

The WorkerDeploymentVersion is required. Worker Deployment Versioning is always enabled for serverless workers. Each Workflow must declare a versioning behavior at registration time, either AutoUpgrade or Pinned.

The Options callback gives you access to the same registration methods you use with a standard Worker: RegisterWorkflow, RegisterWorkflowWithOptions, RegisterActivity, RegisterActivityWithOptions, and RegisterNexusService.

Configuration

The lambdaworker package automatically loads Temporal client configuration from a TOML config file and environment variables.

Config file resolution order:

  1. Path set in TEMPORAL_CONFIG_FILE environment variable
  2. temporal.toml in $LAMBDA_TASK_ROOT (typically /var/task on Lambda)
  3. temporal.toml in the current working directory

Bundle a temporal.toml file in your Lambda deployment package to configure the connection:

[profile.default]
address = "<your-namespace>.<account>.tmprl.cloud:7233"
namespace = "<your-namespace>.<account>"
[profile.default.tls]
client_cert_path = "client.pem"
client_key_path = "client.key"

You can also use environment variables instead of or in addition to the config file. If no config file is found, only environment variables are used.

Encrypt sensitive values like TLS keys or API keys using AWS KMS.

Overriding defaults in the callback:

You can override any client or Worker option directly in the callback. User overrides are applied last and always take precedence.

func(opts *lambdaworker.Options) error {
opts.TaskQueue = "my-task-queue"
opts.ClientOptions.Namespace = "custom-namespace"
opts.WorkerOptions.MaxConcurrentActivityExecutionSize = 5
opts.ShutdownDeadlineBuffer = 10 * time.Second

opts.RegisterWorkflow(MyWorkflow)
opts.RegisterActivity(MyActivity)
return nil
}

Lambda-tuned defaults

The lambdaworker package applies conservative defaults suited to short-lived Lambda invocations. These differ from standard Worker defaults to avoid overcommitting resources in a constrained environment.

SettingLambda default
MaxConcurrentActivityExecutionSize2
MaxConcurrentWorkflowTaskExecutionSize10
MaxConcurrentLocalActivityExecutionSize2
MaxConcurrentNexusTaskExecutionSize5
MaxConcurrentActivityTaskPollers1
MaxConcurrentWorkflowTaskPollers2
MaxConcurrentNexusTaskPollers1
WorkerStopTimeout5 seconds
DisableEagerActivitiesAlways true
Sticky cache size100
ShutdownDeadlineBuffer7 seconds

DisableEagerActivities is always true and cannot be overridden. Eager Activities require a persistent connection, which Lambda invocations don't maintain.

The ShutdownDeadlineBuffer controls how much time before the Lambda deadline the Worker begins its graceful shutdown. The default is WorkerStopTimeout + 2 seconds.

Observability

The lambdaworker/otel sub-package provides OpenTelemetry integration with defaults configured for the AWS Distro for OpenTelemetry (ADOT) Lambda layer.

import (
lambdaworker "go.temporal.io/sdk/contrib/aws/lambdaworker"
otel "go.temporal.io/sdk/contrib/aws/lambdaworker/otel"
"go.temporal.io/sdk/worker"
"go.temporal.io/sdk/workflow"
)

func main() {
lambdaworker.RunWorker(worker.WorkerDeploymentVersion{
DeploymentName: "my-app",
BuildID: "build-1",
}, func(opts *lambdaworker.Options) error {
opts.TaskQueue = "my-task-queue"

if err := otel.ApplyDefaults(opts, &opts.ClientOptions, otel.Options{}); err != nil {
return err
}

opts.RegisterWorkflowWithOptions(MyWorkflow, workflow.RegisterOptions{
VersioningBehavior: workflow.VersioningBehaviorAutoUpgrade,
})
opts.RegisterActivity(MyActivity)

return nil
})
}

ApplyDefaults configures both metrics and tracing. By default, it sends telemetry to localhost:4317, which is the ADOT Lambda layer's default collector endpoint.

If you only need metrics or tracing, use otel.ApplyMetrics or otel.ApplyTracing individually.

Invocation lifecycle

Each Lambda invocation runs through the following steps:

  1. Deadline check. The handler checks the Lambda invocation deadline and confirms enough time remains to do useful work. If less than 1 second remains after subtracting the ShutdownDeadlineBuffer, the invocation exits.
  2. Connect. A new Temporal client is created with an identity derived from the Lambda context (<requestID>@<functionARN>).
  3. Start. A Worker starts on the configured Task Queue with all registered Workflows and Activities.
  4. Poll. The Worker polls for and processes tasks until the invocation deadline minus the ShutdownDeadlineBuffer.
  5. Drain. The Worker stops accepting new tasks and finishes any in-progress work within the WorkerStopTimeout.
  6. Shutdown hooks. Any functions registered with OnShutdown run in registration order. Use this for cleanup like flushing telemetry.
  7. Close. The client connection closes.

The client and Worker are created fresh on each invocation. There is no connection reuse across invocations.