Documentation Index Fetch the complete documentation index at: https://mintlify.com/cadence-workflow/cadence/llms.txt
Use this file to discover all available pages before exploring further.
Introduction
The Cadence Go SDK is the official client library for building workflows and activities in Go. It provides a type-safe, idiomatic Go API for defining durable workflows that can run for days, months, or years.
GitHub Repository Official Cadence Go Client SDK - Star and contribute on GitHub
Installation
Prerequisites
Go 1.18 or higher
Cadence server running (local or remote)
Add Dependency
Go Modules
Specific Version
go get go.uber.org/cadence
Import Packages
import (
" go.uber.org/cadence/client "
" go.uber.org/cadence/worker "
" go.uber.org/cadence/workflow "
" go.uber.org/cadence/activity "
)
Quick Start
1. Define a Workflow
Workflows must be deterministic and cannot directly call external services:
package main
import (
" time "
" go.uber.org/cadence/workflow "
)
// HelloWorkflow is a simple workflow that calls an activity
func HelloWorkflow ( ctx workflow . Context , name string ) ( string , error ) {
// Configure activity options
ao := workflow . ActivityOptions {
ScheduleToStartTimeout : time . Minute ,
StartToCloseTimeout : time . Minute ,
HeartbeatTimeout : time . Second * 20 ,
}
ctx = workflow . WithActivityOptions ( ctx , ao )
// Execute activity
var result string
err := workflow . ExecuteActivity ( ctx , GreetingActivity , name ). Get ( ctx , & result )
if err != nil {
return "" , err
}
return result , nil
}
2. Define an Activity
Activities perform the actual work and can call external services:
package main
import (
" context "
" fmt "
)
// GreetingActivity is an activity that generates a greeting
func GreetingActivity ( ctx context . Context , name string ) ( string , error ) {
// Activities can call external services, databases, etc.
return fmt . Sprintf ( "Hello, %s !" , name ), nil
}
3. Start a Worker
Workers poll for tasks and execute workflows and activities:
package main
import (
" go.uber.org/cadence/client "
" go.uber.org/cadence/worker "
" go.uber.org/zap "
)
func main () {
// Create Cadence client
logger , _ := zap . NewDevelopment ()
cadenceClient , err := client . NewClient ( client . Options {
HostPort : "localhost:7933" ,
Domain : "my-domain" ,
MetricsScope : nil , // Optional: add metrics
})
if err != nil {
logger . Fatal ( "Failed to create client" , zap . Error ( err ))
}
defer cadenceClient . Close ()
// Configure worker options
workerOptions := worker . Options {
Logger : logger ,
MetricsScope : nil ,
MaxConcurrentActivityExecutionSize : 100 ,
MaxConcurrentDecisionTaskExecutionSize : 50 ,
}
// Create worker
cadenceWorker := worker . New ( cadenceClient , "my-task-list" , workerOptions )
// Register workflows
cadenceWorker . RegisterWorkflow ( HelloWorkflow )
// Register activities
cadenceWorker . RegisterActivity ( GreetingActivity )
// Start worker
err = cadenceWorker . Start ()
if err != nil {
logger . Fatal ( "Failed to start worker" , zap . Error ( err ))
}
// Wait indefinitely
select {}
}
4. Execute a Workflow
Start workflow execution from your application:
package main
import (
" context "
" time "
" go.uber.org/cadence/client "
)
func executeWorkflow () {
// Create client
cadenceClient , err := client . NewClient ( client . Options {
HostPort : "localhost:7933" ,
Domain : "my-domain" ,
})
if err != nil {
panic ( err )
}
defer cadenceClient . Close ()
// Configure workflow options
workflowOptions := client . StartWorkflowOptions {
ID : "hello-workflow-1" ,
TaskList : "my-task-list" ,
ExecutionStartToCloseTimeout : time . Minute * 10 ,
DecisionTaskStartToCloseTimeout : time . Minute ,
}
// Start workflow
we , err := cadenceClient . ExecuteWorkflow (
context . Background (),
workflowOptions ,
HelloWorkflow ,
"World" ,
)
if err != nil {
panic ( err )
}
// Wait for result
var result string
err = we . Get ( context . Background (), & result )
if err != nil {
panic ( err )
}
println ( "Workflow result:" , result )
}
Advanced Patterns
Child Workflows
Orchestrate complex processes by composing workflows:
func ParentWorkflow ( ctx workflow . Context ) error {
childOptions := workflow . ChildWorkflowOptions {
ExecutionStartToCloseTimeout : time . Hour ,
TaskList : "child-task-list" ,
}
ctx = workflow . WithChildOptions ( ctx , childOptions )
var result string
err := workflow . ExecuteChildWorkflow ( ctx , ChildWorkflow , "input" ). Get ( ctx , & result )
if err != nil {
return err
}
return nil
}
Signals and Queries
Signals allow external systems to send commands to running workflows: func SignalableWorkflow ( ctx workflow . Context ) error {
var message string
signalChan := workflow . GetSignalChannel ( ctx , "message-signal" )
// Wait for signal
signalChan . Receive ( ctx , & message )
workflow . GetLogger ( ctx ). Info ( "Received signal" , "message" , message )
return nil
}
// Send signal from client
err = cadenceClient . SignalWorkflow (
context . Background (),
"workflow-id" ,
"run-id" ,
"message-signal" ,
"Hello from signal" ,
)
Queries allow external systems to read workflow state without modifying it: func QueryableWorkflow ( ctx workflow . Context ) error {
counter := 0
// Register query handler
err := workflow . SetQueryHandler ( ctx , "counter" , func () ( int , error ) {
return counter , nil
})
if err != nil {
return err
}
// Workflow logic...
counter ++
return nil
}
// Query from client
resp , err := cadenceClient . QueryWorkflow (
context . Background (),
"workflow-id" ,
"run-id" ,
"counter" ,
)
var result int
resp . Get ( & result )
Error Handling and Retries
func RobustWorkflow ( ctx workflow . Context ) error {
// Configure retry policy
retryPolicy := & workflow . RetryPolicy {
InitialInterval : time . Second ,
BackoffCoefficient : 2.0 ,
MaximumInterval : time . Minute ,
MaximumAttempts : 5 ,
NonRetriableErrorReasons : [] string { "invalid-input" },
}
ao := workflow . ActivityOptions {
StartToCloseTimeout : time . Minute * 5 ,
RetryPolicy : retryPolicy ,
}
ctx = workflow . WithActivityOptions ( ctx , ao )
// Execute activity with automatic retries
err := workflow . ExecuteActivity ( ctx , RiskyActivity ). Get ( ctx , nil )
if err != nil {
// Handle error or let workflow fail
return err
}
return nil
}
Local Activities
Local activities are optimized for short, fast operations:
func WorkflowWithLocalActivity ( ctx workflow . Context ) error {
lao := workflow . LocalActivityOptions {
ScheduleToCloseTimeout : time . Second * 5 ,
}
ctx = workflow . WithLocalActivityOptions ( ctx , lao )
// Execute local activity (no history event)
var result string
err := workflow . ExecuteLocalActivity ( ctx , FastActivity ). Get ( ctx , & result )
if err != nil {
return err
}
return nil
}
Worker Configuration
workerOptions := worker . Options {
Logger : logger ,
MetricsScope : metricsScope ,
// Control concurrent workflow executions
MaxConcurrentDecisionTaskExecutionSize : 100 ,
// Control concurrent activity executions
MaxConcurrentActivityExecutionSize : 200 ,
// Control poller threads
MaxConcurrentActivityTaskPollers : 10 ,
MaxConcurrentDecisionTaskPollers : 5 ,
// Enable sticky workflow cache for performance
EnableStickyExecution : true ,
StickyScheduleToStartTimeout : time . Second * 5 ,
}
Worker Lifecycle Management
func runWorkerWithGracefulShutdown () {
cadenceWorker := worker . New ( cadenceClient , "my-task-list" , workerOptions )
// Register workflows and activities
cadenceWorker . RegisterWorkflow ( MyWorkflow )
cadenceWorker . RegisterActivity ( MyActivity )
// Start worker
err := cadenceWorker . Start ()
if err != nil {
panic ( err )
}
// Handle shutdown signals
sigChan := make ( chan os . Signal , 1 )
signal . Notify ( sigChan , os . Interrupt , syscall . SIGTERM )
<- sigChan
// Graceful shutdown
cadenceWorker . Stop ()
}
Testing
Unit Testing Workflows
import (
" testing "
" go.uber.org/cadence/testsuite "
)
func TestHelloWorkflow ( t * testing . T ) {
testSuite := & testsuite . WorkflowTestSuite {}
env := testSuite . NewTestWorkflowEnvironment ()
// Mock activity
env . OnActivity ( GreetingActivity , mock . Anything , "World" ). Return ( "Hello, World!" , nil )
// Execute workflow
env . ExecuteWorkflow ( HelloWorkflow , "World" )
// Verify workflow completed
require . True ( t , env . IsWorkflowCompleted ())
require . NoError ( t , env . GetWorkflowError ())
// Verify result
var result string
require . NoError ( t , env . GetWorkflowResult ( & result ))
require . Equal ( t , "Hello, World!" , result )
}
Sample Repository
Cadence Go Samples Complete examples including:
Hello World workflows
Error handling and retries
Signal and query patterns
Child workflow orchestration
Timer and sleep operations
Saga pattern implementation
Best Practices
Never use time.Now() or rand.Random() directly
Use workflow.Now() and workflow.NewRandom()
Don’t call external services from workflow code
Use activities for all non-deterministic operations
Keep activities idempotent when possible
Implement heartbeats for long-running activities
Use appropriate timeout values
Handle transient errors with retry policies
Start with default settings and tune based on metrics
Monitor queue depth and adjust poller counts
Use sticky execution for better performance
Implement graceful shutdown handlers
Define clear retry policies for activities
Use typed errors for better error classification
Implement compensation logic for saga patterns
Log context information for debugging
Next Steps
Core Concepts Understand workflows, activities, and task lists
Java Client Explore the Java SDK for JVM applications
CLI Reference Manage workflows with the Cadence CLI
Web UI Monitor workflows visually