Serverless Workers on AWS Lambda - Go SDK
The lambdaworker package lets you run a Temporal Serverless Worker on AWS Lambda.
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.
Create and run a Worker in Lambda
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 traditional Worker: RegisterWorkflow, RegisterWorkflowWithOptions, RegisterActivity, RegisterActivityWithOptions, and RegisterNexusService.
Configure the Temporal connection
The lambdaworker package automatically loads Temporal client configuration from a TOML config file and environment variables. Refer to Environment Configuration for more details.
Encrypt sensitive values like TLS keys or API keys. Refer to AWS documentation for options.
Adjust Worker defaults for Lambda
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.
| Setting | Lambda default |
|---|---|
MaxConcurrentActivityExecutionSize | 2 |
MaxConcurrentWorkflowTaskExecutionSize | 10 |
MaxConcurrentLocalActivityExecutionSize | 2 |
MaxConcurrentNexusTaskExecutionSize | 5 |
MaxConcurrentActivityTaskPollers | 1 |
MaxConcurrentWorkflowTaskPollers | 2 |
MaxConcurrentNexusTaskPollers | 1 |
WorkerStopTimeout | 5 seconds |
DisableEagerActivities | Always true |
| Sticky cache size | 100 |
ShutdownDeadlineBuffer | 7 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.
Add observability with OpenTelemetry
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.
For details on how each invocation connects, polls, drains, and shuts down, see How Serverless invocation works.