Skip to content

Your First Workflow & Worker

Outcome: a greetings workflow that queues a greet task and returns Hello Conductor from a worker.

Time: about 5 minutes.

Complete Connect to Conductor first. This guide uses the SDK connection variables configured there: CONDUCTOR_SERVER_URL, plus CONDUCTOR_AUTH_KEY and CONDUCTOR_AUTH_SECRET when your server requires them.

How a worker runs

In this quickstart you build two things: a workflow named greetings — the durable definition that Conductor executes — and a worker — a function in your code that performs one task inside it.

The workflow has a single task of type SIMPLE, which means the work is done by your code rather than by one of Conductor's built-in tasks. Every SIMPLE task has a task type — here, greet. When a running workflow reaches that task, Conductor places it on a queue for that task type. Your worker polls the greet queue, runs your business logic, and reports back COMPLETED or FAILED. Conductor durably persists the result, then advances the workflow to its next task.

Two rules follow from this design:

  • The task type must match exactly between the workflow definition and the worker — otherwise the task sits on a queue that nothing polls.
  • Workers run as ordinary processes in your own infrastructure and deploy and scale independently of the Conductor server. Conductor guarantees at-least-once delivery, meaning the same task can be delivered again after a failure or timeout — so write workers to be idempotent, where running the same task twice produces the same result.
%%{init: {'look': 'handDrawn', 'theme': 'base', 'themeVariables': {'primaryColor': '#eef2ff', 'primaryBorderColor': '#1e40af', 'primaryTextColor': '#1e293b', 'lineColor': '#1e3a8a', 'edgeLabelBackground': '#ffffff', 'clusterBkg': '#fbfcff', 'clusterBorder': '#2563eb', 'fontFamily': '-apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif', 'fontSize': '15px'}, 'flowchart': {'nodeSpacing': 50, 'rankSpacing': 58, 'padding': 14, 'htmlLabels': true, 'curve': 'basis'}}}%%
flowchart LR
    subgraph server["Conductor server"]
        wf["greetings workflow"] --> task["greet task (SIMPLE)"]
    end
    queue[["greet queue"]]
    subgraph worker["Your worker"]
        fn["greet(name)<br/>your business logic"]
    end
    task -- "queues by task type" --> queue
    fn -- "polls" --> queue
    fn -- "reports COMPLETED / FAILED<br/>Conductor persists result, advances workflow" --> task

Language-specific quickstart

Choose a language to reveal one complete greet worker and the matching greetings workflow. The examples are adapted from the maintained SDK hello-world worker examples.

Choose a language to reveal its install, worker, workflow, and run steps.

1. Install Python support

pip install conductor-python

2. Save the worker and workflow app

Save as quickstart.py:

from conductor.client.automator.task_handler import TaskHandler
from conductor.client.configuration.configuration import Configuration
from conductor.client.orkes_clients import OrkesClients
from conductor.client.workflow.conductor_workflow import ConductorWorkflow
from conductor.client.worker.worker_task import worker_task


@worker_task(task_definition_name="greet", register_task_def=True)
def greet(name: str) -> dict:
    return {"result": f"Hello {name}"}


def main():
    config = Configuration()
    clients = OrkesClients(configuration=config)
    executor = clients.get_workflow_executor()

    workflow = ConductorWorkflow(name="greetings", version=1, executor=executor)
    greet_task = greet(task_ref_name="greet_ref", name=workflow.input("name"))
    workflow >> greet_task
    workflow.output_parameters({"result": greet_task.output("result")})
    workflow.register(overwrite=True)

    with TaskHandler(configuration=config, scan_for_annotated_workers=True) as handler:
        handler.start_processes()
        run = executor.execute(name="greetings", version=1, workflow_input={"name": "Conductor"})
        print(run.output["result"])


if __name__ == "__main__":
    main()

3. Run and verify

python quickstart.py
# Hello Conductor

See the Python SDK guide for worker configuration and production patterns.

Verify durable execution

  1. Open the Conductor UI (<YOUR-CLUSTER-URL> for the local server) and go to Executions → Workflow in the left navigation. Click the newest greetings execution — the completed greet_ref task in the timeline shows result: Hello Conductor.
  2. Now watch durability at work. Your quickstart app exited after printing, so no worker is running. Start another execution with the CLI alone:

    conductor workflow start -w greetings -i '{"name":"Conductor"}'
    
  3. Refresh the executions list: the new run is RUNNING and greet_ref is SCHEDULED — durably queued, waiting for a worker. Nothing is lost.

  4. Run your quickstart app again. The worker polls, the waiting task completes, and the execution finishes with result: Hello Conductor.

Troubleshooting

  • greet_ref stays SCHEDULED even with the app running: the worker is not polling the greet task type — confirm the worker is running and its task type is exactly greet.
  • Registration says the definition already exists: bump the version or update the local test definition.
  • greet_ref is FAILED: inspect the task's input, output, and failure reason in the UI, fix the worker, and start a new execution.

Keep learning

Next: Run your first agent — the same durable execution model, applied to an LLM-powered agent.

Prefer no code? Run a workflow from JSON registers a two-step workflow with the CLI alone. The SDKs landing page links to Go, Ruby, Rust, and the language-specific reference material and production guidance for every supported SDK.