Conductor: self-hosted durable execution for workflows and AI agents
Conductor is an event driven agentic workflow engine providing durable and highly resilient execution engine for applications and AI Agents
At a glance
- What is it?
- Conductor is an Apache-2.0 Java workflow engine that persists every step of a graph so crashes and restarts do not lose state. It is aimed at teams that want orchestration as a versioned, inspectable definition rather than code buried in a service.
- Who is it for?
- Adopt Conductor if you need a self-hosted, Apache-2.0 orchestrator with polyglot workers and a declarative graph, and if you are willing to run a JVM server plus a persistence backend yourself. Do not adopt it if you want a managed control plane, or if your workflows are short enough that a queue and a retry loop already suffice.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What Conductor solves, and who ends up running it
Long-running processes that span several services break in an awkward place. A request handler calls an API, waits for a human approval, then fans out to twenty workers. If the process dies halfway, the caller has no record of which steps completed, and the retry either duplicates work or silently skips it. Conductor moves that state out of the calling service and into a server that persists every task transition.
The README frames this as durable execution: "Every step is persisted. Survives crashes, restarts, and network failures with configurable retries and timeouts." The workflow definition, not the application code, decides the order of execution. Workers stay plain code in whatever language the team already uses, and the orchestration layer stays a versioned, machine-readable graph.
That split suits platform teams running many services, and it suits teams building AI agents where a loop of reason, tool call, and evaluate needs to survive a pod restart. It does not suit a single service with one background job. In that case a queue plus a retry loop is less machinery than a JVM server and a persistence backend.
How the execution model actually works
A workflow is a JSON document with a name, a version, and a list of tasks. Each task has a name, a taskReferenceName, and a type. The type determines who executes it: a worker task is polled by your code, while built-in task types such as HTTP calls or LLM calls are executed by the server itself. The README's quickstart workflow is described as calling an API and parsing the response with no workers needed, which is the built-in task path in practice.
The repository layout shows the rest of the architecture. core/ holds the engine, common-persistence/ sits alongside cassandra-persistence/, es8-persistence/, and other storage modules, and kafka-event-queue/ and amqps/ are separate modules for messaging. That structure indicates persistence and the event queue are pluggable rather than fixed. The README states 5 persistence backends and 6 message brokers, without naming them in that line, so the module directories are the reliable place to check which ones exist.
Workers poll the server, execute, and report back. Because the server owns the state, an execution can be inspected and then restarted, rerun, retried, paused, resumed, or terminated, subject to the workflow's policy. Dynamic forks, tasks, and sub-workflows can be resolved at runtime, which is what makes the adaptive-graph claim more than marketing: the graph can branch on values that only exist during execution. The README adds a caution that generated workflow definitions should be validated before starting them, which is the right instinct when a definition is produced by a model rather than a human.
Installing Conductor and running a first workflow
The README lists two prerequisites: Node.js v16 or later and Java 21 or later. With both installed, the CLI installs globally and starts a server on port 8080.
npm install -g @conductor-oss/conductor-cli
conductor server startAfter that command, the README says to open http://localhost:8080, where the built-in ui-next UI is served. The server JAR is cached at ~/.conductor-cli/, and the README notes that an older cached version can be forced to refresh with `conductor server start latest`, or by deleting `~/.conductor-cli/conductor-server-latest.jar` before starting again.
The first workflow is fetched from the repository and created through the CLI. The README describes this one as calling an API and parsing the response, so no worker is required.
curl -s https://raw.githubusercontent.com/conductor-oss/conductor/main/docs/quickstart/workflow.json -o workflow.json
conductor workflow create workflow.jsonRunning create twice returns an error the second time because the workflow already exists. The README calls this expected and points to `conductor workflow update` for changes. Starting the workflow with the sync flag waits for the result rather than returning immediately.
conductor workflow start -w hello_workflow --syncIf you would rather not run the CLI, the README gives a Docker image that includes the UI. The UI is exposed on port 5000 and the API on port 8080.
docker run -p 5000:5000 -p 8080:8080 conductoross/conductor:nextThe README states that every CLI command has an equivalent cURL or API call, so the CLI is a convenience layer rather than a separate control path.
Where Conductor is the wrong choice
The operational surface is the first limitation. You are running a JVM server, choosing a persistence backend, and choosing a message broker. The repository makes that choice explicit by shipping separate modules for Cassandra, Elasticsearch 8, S3, GCS, and Azure Blob storage, plus Kafka and AMQP queues. Each combination is a deployment you have to size, back up, and upgrade. A team without anyone who wants to own that will find the engine heavier than the problem it solves.
The version situation deserves attention. The most recent releases listed are v3.33.0-rc1 and v3.33.0-rc2, both release candidates, alongside v3.32.3 as the newest non-RC tag. A release candidate is not the same commitment as a stable tag, and the README does not document a rollback procedure for downgrading a server whose state lives in a persistence backend. If you run an RC, you are accepting that gap.
The documentation is also thinner than the feature list in places. The README says 5 persistence backends and 6 message brokers but does not enumerate them in that sentence, so the module directories are the source of truth. The README does not document rollback, and it does not describe what happens to in-flight executions during a server upgrade. Those are questions to answer before production, not after.
Finally, the AI task types are a real feature but not a reason on their own to adopt the engine. If all you need is an LLM call with a retry, an SDK call inside your application is simpler than a workflow graph.
Conductor against Temporal and Airflow
Temporal is the closest comparison in intent. It also provides durable execution, but it puts the workflow logic in code: you write a workflow function in a supported language and the SDK replays it deterministically to reconstruct state. Conductor inverts that. The graph is a JSON definition stored and versioned on the server, and workers are stateless pollers that report results. The practical difference shows up when a non-engineer needs to read what a process does, or when a definition is generated at runtime. A declarative graph is inspectable without reading code, and Conductor's dynamic forks and runtime-resolved sub-workflows are designed for graphs that change shape during execution. The cost is that complex branching is expressed in the definition format rather than in ordinary control flow.
Airflow is a different tool aimed at a different problem. It schedules batch DAGs on a timetable and is built around the scheduler and the data interval. Conductor is event driven and oriented toward request and agent flows that start when something happens, not when a clock says so. Choosing Airflow for a human-approval step that may wait days is fighting the model; choosing Conductor for a nightly ETL chain is equally mismatched. The README's own framing, an event driven engine for microservices and agents, marks where it expects to be used.
Licence, maintenance and the cost of upgrading
Conductor is Apache-2.0, which permits commercial use, modification, and redistribution under the terms of that licence. That removes the source-availability question that comes with some orchestration products, and the README's "self-hosted, no lock-in" line points at the same property. It does not remove the operational cost: you still run the server, the database, and the broker. For anything beyond a licence question, read the LICENSE file and, if the stakes are high, a lawyer.
On maintenance, the repository is not archived, and the last push was on 2026-09-10, with v3.33.0-rc2 tagged the same day. The README states the project originated at Netflix and is maintained by Orkes and the community, and the presence of CONTRIBUTING.md, SECURITY.md, ROADMAP.md, and CHANGELOG.md in the repository root is consistent with that. The CHANGELOG.md file is the place to look for what changed between the tag you run and the tag you are considering.
Upgrade cost is dominated by the persistence layer, not the JAR. Because workflow state lives in the database, the upgrade path is server version plus schema plus backend version, and the README does not document a downgrade path. The CLI adds a smaller wrinkle: the cached server JAR at ~/.conductor-cli/ can be stale, which is why the README documents `conductor server start latest` and the manual cache deletion. Teams that pin versions should pin deliberately rather than relying on the cache.
Editorial conclusion
Adopt Conductor if you need a self-hosted, Apache-2.0 orchestrator with polyglot workers and a declarative graph, and if you are willing to run a JVM server plus a persistence backend yourself. Do not adopt it if you want a managed control plane, or if your workflows are short enough that a queue and a retry loop already suffice. Before committing, verify the persistence backend and message broker you intend to use actually appear in the repository's module list, and check the release notes for the version you plan to run, since the most recent releases listed are v3.33.0-rc1 and v3.33.0-rc2, both release candidates, with v3.32.3 as the newest non-RC tag.
Frequently asked questions
How do I install Conductor?
Install Node.js v16 or later and Java 21 or later, then run npm install -g @conductor-oss/conductor-cli followed by conductor server start. The server comes up on http://localhost:8080 with the built-in ui-next UI. A Docker image, conductoross/conductor:next, is also documented, exposing the UI on port 5000 and the API on port 8080.
How do I use Conductor to run a workflow?
Create a workflow definition with conductor workflow create workflow.json, then start it with conductor workflow start -w hello_workflow --sync. The README's quickstart workflow calls an API and parses the response, so no worker is needed for that first run. Every CLI command has an equivalent cURL or API call.
How do I use Conductor with AI agents?
The README describes an autonomous think-act agent that discovers tools via MCP, reasons with an LLM, calls the chosen tool, and repeats until done. It uses task types including LIST_MCP_TOOLS, LLM_CHAT_COMPLETE, DO_WHILE, and SWITCH inside a single workflow definition. The README advises validating generated workflow definitions before starting them.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/conductor-oss-conductor)
Community notes