Cadence is a distributed, scalable, durable, and highly available orchestration engine to execute asynchronous long-running business logic in a scalable and resilient way. https://cadenceworkflow.io
  • Go 99.1%
  • CQL 0.3%
  • Shell 0.3%
  • Go Template 0.2%
  • Makefile 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Theis Mathiassen 5587d6cc14
feat(shard-distributor): add greedy load-balancing mode for rebalancing and initial placement (#8030)
<!-- If you are new to contributing or want a refresher, please read
./pull_request_guidance.md -->

**What changed?**
Refactored load-balancing code out of `processor.go` and the old
`handler/loadbalance` package into a dedicated `loadbalancer` package
with strategy subpackages (`loadbalancer/strategy/greedy` and
`loadbalancer/strategy/naive`).

Introduced a shared planning contract:
- `loadbalancer/plan.Placement` for initial shard placement
- `loadbalancer/plan.Move` for rebalancing moves

The load balancer now produces plans instead of applying assignment
changes directly. `handler` applies placement plans for ephemeral
assignment, and `processor` applies rebalance move plans before building
the final assignment state. This keeps etcd writes, election guards,
migration/shadow-mode behavior, and response construction outside the
strategy packages.

Added greedy rebalancing in `greedy.Rebalance`, using smoothed shard
load from shard heartbeats to identify and correct load imbalances.
Added optional tuning controls (Defaults should work well):
- `MoveBudgetProportion` caps shards moved per rebalance pass.
- `HysteresisUpperBand` and `HysteresisLowerBand` avoid rebalancing
until executor load deviates meaningfully from the namespace average.
- `SevereImbalanceRatio` relaxes destination selection when imbalance is
extreme.
- `PerShardCooldown` prevents the same shard from moving too frequently
in greedy mode.

Added namespace-filtered dynamic config keys for greedy tuning
parameters (`ShardDistributorLoadBalancingGreedy*`).

Added imbalance and staleness metrics, including reported-load and
smoothed-load CV/max-over-mean metrics plus smoothed-load missing/stale
ratios.

**Why?**
Shard load can drift over time as workloads change or executors join and
leave the cluster. Greedy rebalancing uses actual load signals instead
of only shard counts, which should produce better distribution for
uneven shard workloads.

Separating planning from execution also makes the algorithms easier to
test, reason about, and extend with additional strategies.

**How did you test it?**
Added/updated tests for:
- Greedy rebalancing: convergence, skipping non-beneficial moves,
per-shard cooldown, severe-imbalance relaxation, move-budget capping,
and destination eligibility.
- Naive rebalancing: deviation threshold, hottest-shard selection, and
empty-executor handling.
- Initial placement for both strategies: selection logic, tie-breaking,
draining exclusion, and no-active-executor errors.
- Loadbalancer dispatch by mode and unsupported mode handling.
- Processor integration for both naive and greedy rebalance paths.
- Handler orchestration, error wrapping, and invalid mode handling.

Ran:
```bash
ETCD=1 go test -race ./service/sharddistributor/...
```

**Potential risks**
Misconfiguration of hysteresis: if bands are set too narrow the system
may move shards unnecessarily; if too wide, imbalances may persist too
long. This is mitigated by conservative default values.

**Release notes**
N/A

**Documentation Changes**
N/A

---------

Signed-off-by: Andreas Holt <6665487+AndreasHolt@users.noreply.github.com>
Signed-off-by: Theis Randeris Mathiassen <theis@tmathiassen.dk>
Signed-off-by: Andreas Holt
Co-authored-by: Andreas Holt <6665487+AndreasHolt@users.noreply.github.com>
2026-05-17 10:19:19 +02:00
.agents docs: Add additional non-determinism rules to workflow guide for agents (#7806) 2026-03-31 17:57:47 +00:00
.claude/skills/cadence-pr-create chore: add Claude Code PR create skill (#7846) 2026-03-25 13:41:25 -07:00
.cursor/rules docs: Add additional non-determinism rules to workflow guide for agents (#7806) 2026-03-31 17:57:47 +00:00
.gen feat(schedule): wire Schedule APIs through Thrift transport layer (#8079) 2026-05-12 09:31:22 -07:00
.gitar/rules docs: Move pull request template documentation to its own guidance file (#7717) 2026-02-26 13:15:58 -08:00
.github chore: Upgrade github codecov action to v5 (#8048) 2026-05-07 10:06:48 -07:00
bench chore: Upgrade cadence-idl, yarpc, grpc-go (#7849) 2026-04-02 07:50:29 -07:00
canary Replace docker-compose commands with docker compose (#7029) 2025-07-03 17:09:45 -07:00
client fix(metrics): emit correct is_retry tag on retried persistence and client calls (#8049) 2026-05-07 21:20:16 +02:00
cmd feat(schedule): wire Schedule APIs through Thrift transport layer (#8079) 2026-05-12 09:31:22 -07:00
common feat(shard-distributor): add greedy load-balancing mode for rebalancing and initial placement (#8030) 2026-05-17 10:19:19 +02:00
config fix: trim workflow timer tasks on workflow close and deletion (#7941) 2026-05-11 18:16:22 -07:00
docker feat(simulation): make history simulation params configurable per scenario (#7952) 2026-05-04 13:03:30 +02:00
docs docs: persistence.md (consistent name for postgresql) (#6429) 2026-05-04 09:37:48 -07:00
environment Write unit tests for env.go and a few exclusion updates (#5827) 2024-04-01 14:05:12 -07:00
host feat(replication): persist dlq task in standby cluster (#8023) 2026-05-15 11:20:31 -07:00
idls@6a3d47b53b feat(schedule): wire Schedule APIs through Thrift transport layer (#8079) 2026-05-12 09:31:22 -07:00
internal/tools fix: trim workflow timer tasks on workflow close and deletion (#7941) 2026-05-11 18:16:22 -07:00
logos docs: Add DoorDash to ADOPTERS.md (#7776) 2026-03-03 09:17:40 -08:00
proto chore(shard-distributor): cleanup unused migration modes (#7984) 2026-04-21 15:48:41 +02:00
schema fix: trim workflow timer tasks on workflow close and deletion (#7941) 2026-05-11 18:16:22 -07:00
scripts chore: Upgrade cadence-idl, yarpc, grpc-go (#7849) 2026-04-02 07:50:29 -07:00
service feat(shard-distributor): add greedy load-balancing mode for rebalancing and initial placement (#8030) 2026-05-17 10:19:19 +02:00
simulation feat(simulation): make history simulation params configurable per scenario (#7952) 2026-05-04 13:03:30 +02:00
testflags [sharddistributor][leaderelection] Introduce leader election mechanism (#6889) 2025-05-08 19:19:44 +02:00
tools chore: fix sqlite tests (#8075) 2026-05-15 10:22:46 -07:00
.dockerignore Go version bump (#5367) 2023-08-01 11:11:21 +02:00
.envrc feat: Add direnv support for local development (#7188) 2025-08-20 12:30:50 +02:00
.fossa.yml Fossa integration (#3162) 2020-04-03 08:42:51 -07:00
.gitattributes Move some proto definitions to admin package (#4861) 2022-06-09 10:11:08 +03:00
.gitignore chore: add Claude Code PR create skill (#7846) 2026-03-25 13:41:25 -07:00
.gitmodules Change License to Apache 2.0 (#6882) 2025-05-02 18:39:01 -07:00
ADOPTERS.md docs: Add DoorDash to ADOPTERS.md (#7776) 2026-03-03 09:17:40 -08:00
AGENTS.md docs: Add additional non-determinism rules to workflow guide for agents (#7806) 2026-03-31 17:57:47 +00:00
CHANGELOG.md Update change log for release v1.3.3 (#7139) 2025-08-06 18:51:16 +00:00
CLAUDE.md docs: Add additional non-determinism rules to workflow guide for agents (#7806) 2026-03-31 17:57:47 +00:00
CLAUDE.md~master docs: Add additional non-determinism rules to workflow guide for agents (#7806) 2026-03-31 17:57:47 +00:00
codecov.yml Replication/failover simulation operations: startWorkflow, failover and validate (#6655) 2025-02-11 18:54:14 +00:00
CONTRIBUTING.md Correct SQLite command and fix broken markdown link in CONTRIBUTING.md (#7349) 2025-10-20 18:36:29 +00:00
Dockerfile ci: Pin cassandra-driver and cqlsh to an old version (#7965) 2026-04-17 05:30:34 +05:30
go.mod feat(schedule): wire Schedule APIs through Thrift transport layer (#8079) 2026-05-12 09:31:22 -07:00
go.sum feat(schedule): wire Schedule APIs through Thrift transport layer (#8079) 2026-05-12 09:31:22 -07:00
go.work chore: Upgrade cadence-idl, yarpc, grpc-go (#7849) 2026-04-02 07:50:29 -07:00
go.work.sum feat(schedule): wire Schedule APIs through Thrift transport layer (#8079) 2026-05-12 09:31:22 -07:00
LICENSE Change License to Apache 2.0 (#6882) 2025-05-02 18:39:01 -07:00
MAINTAINERS.md docs: Update maintainers and TSC (#7939) 2026-04-10 11:57:47 -07:00
Makefile chore: Upgrade cadence-idl, yarpc, grpc-go (#7849) 2026-04-02 07:50:29 -07:00
NOTICE Change License to Apache 2.0 (#6882) 2025-05-02 18:39:01 -07:00
PROPOSALS.md Update github org/repos in markdown files (#6524) 2024-11-25 23:34:02 +00:00
README.md docs: Add KubeStellar Console guided install reference (#7862) 2026-04-01 14:59:15 -07:00
RELEASES.md Add admin CLI scan command for unsupported workflows (#3824) 2020-12-03 23:41:45 -08:00
revive.toml Update revive to catch more defer/recover badness (#4917) 2022-07-26 16:56:26 -07:00

Cadence

Build Status Coverage Slack Status Github release License

Cadence Workflow is an open-source platform since 2017 for building and running scalable, fault-tolerant, and long-running workflows. This repository contains the core orchestration engine and tools including CLI, schema managment, benchmark and canary.

Getting Started

Cadence backend consists of multiple services, a database (Cassandra/MySQL/PostgreSQL) and optionally Kafka+Elasticsearch. As a user, you need a worker which contains your workflow implementation. Once you have Cadence backend and worker(s) running, you can trigger workflows by using SDKs or via CLI.

  1. Start cadence backend components locally
docker compose -f docker/docker-compose.yml up
  1. Run the Samples

Try out the sample recipes for Go or Java.

  1. Visit UI

Visit http://localhost:8088 to check workflow histories and detailed traces.

Kubernetes Deployment

For a guided Kubernetes installation experience, KubeStellar Console provides a step-by-step mission that deploys Cadence using the official Helm chart from cadence-charts. The mission includes pre-flight checks, validation, troubleshooting, and rollback support.

Client Libraries

You can implement your workflows with one of our client libraries:

You can also use iWF as a DSL framework on top of Cadence.

CLI

Cadence CLI can be used to operate workflows, tasklist, domain and even the clusters.

You can use the following ways to install Cadence CLI:

  • Use brew to install CLI: brew install cadence-workflow
    • Follow the instructions if you need to install older versions of CLI via homebrew. Usually this is only needed when you are running a server of a too old version.
  • Use docker image for CLI: docker run --rm ubercadence/cli:<releaseVersion> or docker run --rm ubercadence/cli:master . Be sure to update your image when you want to try new features: docker pull ubercadence/cli:master
  • Build the CLI binary yourself, check out the repo and run make cadence to build all tools. See CONTRIBUTING for prerequisite of make command.
  • Build the CLI image yourself, see instructions

Cadence CLI is a powerful tool. The commands are organized by tabs. E.g. workflow->batch->start, or admin->workflow->describe.

Please read the documentation and always try out --help on any tab to learn & explore.

UI

Try out Cadence Web UI to view your workflows on Cadence. (This is already available at localhost:8088 if you run Cadence with docker compose)

Other binaries in this repo

Bench/stress test workflow tools

See bench documentation.

Periodical feature health check workflow tools(aka Canary)

See canary documentation.

Schema tools for SQL and Cassandra

The tools are for manual setup or upgrading database schema

The easiest way to get the schema tool is via homebrew.

brew install cadence-workflow also includes cadence-sql-tool and cadence-cassandra-tool.

  • The schema files are located at /usr/local/etc/cadence/schema/.
  • To upgrade, make sure you remove the old ElasticSearch schema first: mv /usr/local/etc/cadence/schema/elasticsearch /usr/local/etc/cadence/schema/elasticsearch.old && brew upgrade cadence-workflow. Otherwise ElasticSearch schemas may not be able to get updated.
  • Follow the instructions if you need to install older versions of schema tools via homebrew. However, easier way is to use new versions of schema tools with old versions of schemas. All you need is to check out the older version of schemas from this repo. Run git checkout v0.21.3 to get the v0.21.3 schemas in the schema folder.

Contributing

We'd love your help in making Cadence great. Please review our contribution guide.

If you'd like to propose a new feature, first join the CNCF Slack workspace in the #cadence-users channel to start a discussion.

Please visit our documentation site for production/cluster setup.

Learning Resources

See Maxim's talk at Data@Scale Conference for an architectural overview of Cadence.

Visit cadenceworkflow.io to learn more about Cadence. Join us in Cadence Documentation project. Feel free to raise an Issue or Pull Request there.

Community

  • Github Discussion
    • Best for Q&A, support/help, general discusion, and annoucement
  • Github Issues
    • Best for reporting bugs and feature requests
  • StackOverflow
    • Best for Q&A and general discusion
  • Slack - Join #cadence-users channel on CNCF Slack
    • Best for contributing/development discussion

Stars over time

Stargazers over time

License

Apache 2.0 License, please see LICENSE for details.