Temporal Go SDK [](https://github.com/temporalio/sdk-go/actions/workflows/ci.yml) [](https://pkg.go.dev/go.temporal.io/sdk)
July 16, 2026 ยท View on GitHub

Temporal Go SDK

Temporal is a distributed, scalable, durable, and highly available orchestration engine used to execute asynchronous long-running business logic in a scalable and resilient way.
"Temporal Go SDK" is Temporal's framework for authoring workflows and activities using the Go language.
Add the SDK to your project
The core Temporal Go SDK packages, including client, worker, and workflow,
are released together as the go.temporal.io/sdk module.
From your application's Go module, run:
go get go.temporal.io/sdk@latest
Then import the packages you need, such as:
import (
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/worker"
"go.temporal.io/sdk/workflow"
)
The integrations and tools under contrib are released as separate
Go modules. See each package's README for its module path and version.
Getting started
See samples to get started.
Documentation is available here. You can also find the API documentation here.
Using slog
If using Go version 1.21+ the Go SDK provides built in integration with the standard slog package.
package main
import (
"log/slog"
"os"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/log"
"go.temporal.io/sdk/worker"
)
func main() {
clientOptions := client.Options{
Logger: log.NewStructuredLogger(
slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
AddSource: true,
Level: slog.LevelDebug,
}))),
}
temporalClient, err := client.Dial(clientOptions)
// ...
}
Workflow determinism checker
See contrib/tools/workflowcheck for a tool to detect non-determinism in Workflow Definitions.
Contributing
We'd love your help in making the Temporal Go SDK great. Please review our contribution guidelines.
Development
Prerequisites
Local development workflow
The canonical local commands are provided by the build tool in internal/cmd/build.
Tests are managed through the build tool at internal/cmd/build. This tool handles starting an embedded Temporal dev
server with the required dynamic configs and search attributes, enforces consistent test flags (-race, -count 1, no caching),
and manages coverage collection, so you don't need to manually configure a server or remember the right flags.
cd internal/cmd/build
Run static analysis checks:
go run . check
Run unit tests (all packages except test/):
go run . unit-test
Run integration tests with an embedded Temporal dev server:
go run . integration-test -dev-server
If you omit -dev-server, integration tests connect to a server already running on localhost:7233.
Running specific tests
Use -run with the same semantics as go test -run.
Unit tests:
go run . unit-test -run "TestMyFunction"
Integration tests:
# Single test in a suite
go run . integration-test -dev-server -run "TestIntegrationSuite/TestMyTest"
# Entire suite
go run . integration-test -dev-server -run "TestWorkerTunerTestSuite"
Coverage
Unit test coverage (writes per-package profiles under .build/coverage):
go run . unit-test -coverage
Integration test coverage:
go run . integration-test -dev-server -coverage-file integration-test.out
Merge coverage files:
go run . merge-coverage-files coverage.out
Go module housekeeping
If dependencies change, tidy all modules:
find . -name go.mod -execdir go mod tidy \;
Pull request checklist
Before opening or updating a pull request:
- Run
go run . checkfrominternal/cmd/build. - Run relevant tests (
unit-testand, when needed,integration-test -dev-server). - Keep changes focused and include tests for behavior changes.
- Update documentation/comments when public behavior changes.
Go SDK upgrading past v1.25.1
Go SDK version v1.26.0 switched from using https://github.com/gogo/protobuf to https://github.com/golang/protobuf. While this migration is mostly internal there are a few user visible changes to be aware of:
Change in types
time.Timein proto structs will now be timestamppb.Timestamptime.Durationwill now be durationpb.Duration- V2-generated structs embed locks, so you cannot dereference them.
Incompatible proto/json encoding
Proto enums will, when formatted to JSON, now be in SCREAMING_SNAKE_CASE rather than PascalCase. * If trying to deserialize old JSON with PascalCase to proto use go.temporal.io/api/temporalproto.
If users used Temporal proto types in their Workflows, such as for activity output, users may need to modify the default data converter to handle these payloads.
converter.NewProtoJSONPayloadConverterWithOptions(converter.ProtoJSONPayloadConverterOptions{
LegacyTemporalProtoCompat: true,
}),
While upgrading from Go SDK version < 1.26.0 to a version >= 1.26.0 users may want to also bias towards using
proto binary to avoid any potential incompatibilities due to having clients serialize messages with incompatible proto/json format.
On clients running Go SDK < 1.26.0
converter.NewCompositeDataConverter(
converter.NewNilPayloadConverter(),
converter.NewByteSlicePayloadConverter(),
converter.NewProtoPayloadConverter(),
converter.NewProtoJSONPayloadConverterWithOptions(),
converter.NewJSONPayloadConverter(),
)
On clients running Go SDK >= 1.26.0
converter.NewCompositeDataConverter(
converter.NewNilPayloadConverter(),
converter.NewByteSlicePayloadConverter(),
converter.NewProtoPayloadConverter(),
converter.NewProtoJSONPayloadConverterWithOptions(converter.ProtoJSONPayloadConverterOptions{
LegacyTemporalProtoCompat: true,
}),
converter.NewJSONPayloadConverter(),
)
Note: Payloads encoded with proto/binary will not be readable in the Temporal web UI.
License
MIT License, please see LICENSE for details.