Overview
Cadence server configuration consists of two layers:
Static Configuration : YAML files that define core server settings (loaded at startup)
Dynamic Configuration : Runtime settings that can be updated without restart
This guide covers both configuration types and common configuration patterns.
Static Configuration
Static configuration is defined in YAML files located in the config/ directory. The configuration is organized into several sections.
Configuration File Structure
log : # Logging configuration
persistence : # Database configuration
ringpop : # Cluster membership
services : # Service-specific settings
clusterGroupMetadata : # Multi-cluster setup
archival : # History archival
domainDefaults : # Default domain settings
dynamicconfig : # Dynamic config file path
blobstore : # Blob storage settings
authorization : # Auth configuration
Logging Configuration
Configure server logging output:
log :
stdout : true # Output to stdout
level : "info" # Log level: debug, info, warn, error
levelKey : "level" # JSON field name for log level
For production deployments, use info or warn level. The debug level generates significant log volume and should only be used for troubleshooting.
Persistence Configuration
Cadence requires two types of persistence stores:
defaultStore : Core workflow execution state
visibilityStore : Workflow search and listing
Cassandra Configuration
persistence :
defaultStore : cass-default
visibilityStore : cass-visibility
numHistoryShards : 1024
datastores :
cass-default :
nosql :
pluginName : "cassandra"
hosts : "10.0.1.10,10.0.1.11,10.0.1.12"
keyspace : "cadence"
user : "cadence_user"
password : "${CASSANDRA_PASSWORD}"
datacenter : "us-east-1a"
consistency : LOCAL_QUORUM
serialConsistency : LOCAL_SERIAL
connectTimeout : 2s
timeout : 5s
maxConns : 2
cass-visibility :
nosql :
pluginName : "cassandra"
hosts : "10.0.1.10,10.0.1.11,10.0.1.12"
keyspace : "cadence_visibility"
user : "cadence_user"
password : "${CASSANDRA_PASSWORD}"
MySQL Configuration
persistence :
defaultStore : mysql-default
visibilityStore : mysql-visibility
numHistoryShards : 1024
datastores :
mysql-default :
sql :
pluginName : "mysql"
databaseName : "cadence"
connectAddr : "mysql.example.com:3306"
connectProtocol : "tcp"
user : "cadence"
password : "${MYSQL_PASSWORD}"
maxConns : 20
maxIdleConns : 20
maxConnLifetime : "1h"
connectAttributes :
tx_isolation : "READ-COMMITTED" # Required for MySQL 5.6
mysql-visibility :
sql :
pluginName : "mysql"
databaseName : "cadence_visibility"
connectAddr : "mysql.example.com:3306"
connectProtocol : "tcp"
user : "cadence"
password : "${MYSQL_PASSWORD}"
maxConns : 2
maxIdleConns : 2
PostgreSQL Configuration
persistence :
defaultStore : postgres-default
visibilityStore : postgres-visibility
numHistoryShards : 1024
datastores :
postgres-default :
sql :
pluginName : "postgres"
databaseName : "cadence"
connectAddr : "postgres.example.com:5432"
connectProtocol : "tcp"
user : "postgres"
password : "${POSTGRES_PASSWORD}"
maxConns : 20
maxIdleConns : 20
maxConnLifetime : "1h"
postgres-visibility :
sql :
pluginName : "postgres"
databaseName : "cadence_visibility"
connectAddr : "postgres.example.com:5432"
connectProtocol : "tcp"
user : "postgres"
password : "${POSTGRES_PASSWORD}"
maxConns : 2
maxIdleConns : 2
numHistoryShards cannot be changed after initial cluster setup. Plan for your maximum expected cluster size. Typical production values:
Small deployments: 512-1024 shards
Medium deployments: 2048-4096 shards
Large deployments: 8192+ shards
Multiple Database Sharding
For very large scale deployments, Cadence supports sharding across multiple SQL databases:
config/sharded-mysql.yaml
persistence :
defaultStore : mysql-sharded
datastores :
mysql-sharded :
sql :
pluginName : "mysql"
connectProtocol : "tcp"
maxConnLifetime : "1h"
useMultipleDatabases : true
nShards : 4
multipleDatabasesConfig :
- user : "cadence"
password : "${MYSQL_PASSWORD}"
connectAddr : "mysql-shard0.example.com:3306"
databaseName : "cadence0"
- user : "cadence"
password : "${MYSQL_PASSWORD}"
connectAddr : "mysql-shard1.example.com:3306"
databaseName : "cadence1"
- user : "cadence"
password : "${MYSQL_PASSWORD}"
connectAddr : "mysql-shard2.example.com:3306"
databaseName : "cadence2"
- user : "cadence"
password : "${MYSQL_PASSWORD}"
connectAddr : "mysql-shard3.example.com:3306"
databaseName : "cadence3"
Service Configuration
Configure individual Cadence services:
services :
frontend :
rpc :
port : 7933 # TChannel port
grpcPort : 7833 # gRPC port
bindOnLocalHost : false # Bind to all interfaces
grpcMaxMsgSize : 33554432
metrics :
prometheus :
timerType : "histogram"
listenAddress : "0.0.0.0:8000"
pprof :
port : 7936
matching :
rpc :
port : 7935
grpcPort : 7835
bindOnLocalHost : false
metrics :
prometheus :
timerType : "histogram"
listenAddress : "0.0.0.0:8001"
history :
rpc :
port : 7934
grpcPort : 7834
bindOnLocalHost : false
metrics :
prometheus :
timerType : "histogram"
listenAddress : "0.0.0.0:8002"
worker :
rpc :
port : 7939
bindOnLocalHost : false
metrics :
prometheus :
timerType : "histogram"
listenAddress : "0.0.0.0:8003"
Metrics Configuration
services :
frontend :
metrics :
prometheus :
timerType : "histogram" # or "summary"
listenAddress : "0.0.0.0:8000"
Ringpop Configuration
Ringpop provides service discovery and cluster membership:
ringpop :
name : cadence
bootstrapMode : hosts # or "dns"
bootstrapHosts :
- "cadence-frontend-0.cadence.svc.cluster.local:7933"
- "cadence-frontend-1.cadence.svc.cluster.local:7933"
- "cadence-history-0.cadence.svc.cluster.local:7934"
- "cadence-matching-0.cadence.svc.cluster.local:7935"
maxJoinDuration : 30s
For Kubernetes deployments, use headless services with DNS-based discovery.
Archival Configuration
Enable workflow history and visibility archival:
archival :
history :
status : "enabled"
enableRead : true
provider :
filestore :
fileMode : "0666"
dirMode : "0766"
gstorage :
credentialsPath : "/etc/cadence/gcp-credentials.json"
visibility :
status : "enabled"
enableRead : true
provider :
filestore :
fileMode : "0666"
dirMode : "0766"
domainDefaults :
archival :
history :
status : "enabled"
URI : "gs://cadence-archive-bucket/history"
visibility :
status : "enabled"
URI : "gs://cadence-archive-bucket/visibility"
Advanced Visibility (ElasticSearch)
Configure ElasticSearch for enhanced workflow search:
config/elasticsearch.yaml
persistence :
defaultStore : cass-default
visibilityStore : cass-visibility
advancedVisibilityStore : es-visibility
datastores :
es-visibility :
elasticsearch :
version : "v7" # or "v6", "opensearch"
url :
scheme : "https"
host : "elasticsearch.example.com:9200"
username : "elastic"
password : "${ES_PASSWORD}"
indices :
visibility : "cadence-visibility-prod"
Multi-cluster Configuration
For cross-datacenter replication:
config/multi-cluster.yaml
clusterGroupMetadata :
failoverVersionIncrement : 10
primaryClusterName : "cluster0"
currentClusterName : "cluster0"
clusterGroup :
cluster0 :
enabled : true
initialFailoverVersion : 0
rpcAddress : "cadence-frontend.us-east-1.example.com:7833"
rpcTransport : "grpc"
cluster1 :
enabled : true
initialFailoverVersion : 1
rpcAddress : "cadence-frontend.eu-west-1.example.com:7833"
rpcTransport : "grpc"
Dynamic Configuration
Dynamic configuration allows runtime updates without service restart. Settings are stored in YAML files that are polled periodically.
Dynamic Config File Setup
dynamicconfig :
client : filebased
filebased :
filepath : "config/dynamicconfig/production.yaml"
pollInterval : "60s" # Check for updates every 60s
Dynamic config uses a constraint-based system:
config/dynamicconfig/production.yaml
# Enable client version checking
frontend.enableClientVersionCheck :
- value : true
constraints : {}
# Set minimum retention days
system.minRetentionDays :
- value : 7
constraints : {}
# Per-domain configuration
history.EnableConsistentQueryByDomain :
- value : true
constraints :
domainName : "critical-workflows"
- value : false
constraints :
domainName : "experimental-workflows"
# Task list specific settings
matching.taskListLoadBalancerStrategy :
- value : "round-robin"
constraints :
domainName : "high-volume-domain"
taskListName : "fast-tasks"
Common Dynamic Config Settings
Rate Limiting
Retention
Task Processing
Replication
frontend.rps :
- value : 2400 # Requests per second
constraints : {}
frontend.domainRPS :
- value : 1200
constraints :
domainName : "high-priority-domain"
Constraint Types
Dynamic config supports three constraint types:
domainName : Apply to specific domain (string)
taskListName : Apply to specific task list (string)
taskType : Apply to task type (int: 0=Decision, 1=Activity)
# Example with all constraint types
setting.example :
- value : "default-value"
constraints : {}
- value : "domain-specific"
constraints :
domainName : "my-domain"
- value : "tasklist-specific"
constraints :
domainName : "my-domain"
taskListName : "my-tasklist"
- value : "activity-specific"
constraints :
domainName : "my-domain"
taskListName : "my-tasklist"
taskType : 1 # Activities only
Environment Variables
Cadence supports environment variable substitution in configuration files:
persistence :
datastores :
default :
sql :
user : "${DB_USER}"
password : "${DB_PASSWORD}"
connectAddr : "${DB_HOST}:${DB_PORT}"
Set variables before starting the server:
export DB_USER = cadence
export DB_PASSWORD = secret
export DB_HOST = postgres . example . com
export DB_PORT = 5432
cadence-server --root config --env production start
Configuration Best Practices
Use environment-specific configs
Maintain separate configuration files for each environment: config/
development.yaml
staging.yaml
production.yaml
dynamicconfig/
development.yaml
staging.yaml
production.yaml
Version control configurations
Store all configuration files in version control (except secrets).
Use secret management
Never commit passwords or keys. Use environment variables or secret management systems: password : "${DB_PASSWORD}" # From env or secret manager
Start with conservative settings
Begin with lower connection pools and rate limits, then tune based on metrics.
Test dynamic config changes
Test dynamic configuration changes in non-production first.
Configuration Validation
Validate your configuration before deploying:
# Start server in dry-run mode (validates config)
cadence-server --root config --env production validate
# Check for syntax errors
yamlint config/production.yaml
Next Steps
Database Setup Configure and initialize your persistence layer
Docker Deployment Deploy with Docker and docker-compose