Worker Labels
Worker labels are key-value pairs that describe worker capabilities. The coordinator uses labels to match tasks to workers via the worker_selector field in DAG definitions.
Every worker also needs worker.coordinators. The examples below assume:
export DAGU_WORKER_COORDINATORS=coordinator-1:50055Setting Labels
CLI Flag
dagu worker --worker.labels gpu=true,memory=64G,region=us-east-1Labels are comma-separated key=value pairs. Keys and values are trimmed of whitespace.
Configuration File
# config.yaml
worker:
coordinators:
- coordinator-1:50055
labels:
gpu: "true"
memory: "64G"
region: "us-east-1"Environment Variable
export DAGU_WORKER_LABELS="gpu=true,memory=64G,region=us-east-1"
export DAGU_WORKER_COORDINATORS=coordinator-1:50055
dagu workerMatching Algorithm
The coordinator's matchesSelector() function evaluates whether a worker is eligible for a task:
- Empty selector matches any worker: a task without
worker_selector(or with an empty map) can run on any available worker. - All selector key-value pairs must match exactly: every key in the selector must exist in the worker's labels with an identical value. Matching is case-sensitive.
- Workers can have extra labels: a worker with
gpu=true,memory=64G,region=us-east-1matches a selector ofgpu: "true"because the worker satisfies all required keys. The extramemoryandregionlabels are ignored.
DAG-Level worker_selector
Set worker_selector at the top of a DAG file to route the entire DAG to a matching worker:
worker_selector:
gpu: "true"
tools:
- astral-sh/uv@0.11.14
steps:
- run: uv run --python 3.13.9 python train.pyWhen the coordinator dispatches this DAG, it selects a worker whose labels include gpu=true.
Step-Level worker_selector
Set worker_selector on a step to dispatch that step's sub-DAG to a different worker than the parent:
steps:
- action: dag.run
with:
dag: train-model
worker_selector:
gpu: "true"
- action: dag.run
with:
dag: generate-report
worker_selector:
region: "us-east-1"Step-level worker_selector is only valid on actions that launch sub-DAGs:
| Action | Supports worker_selector |
|---|---|
dag.run | Yes |
dag.enqueue | Yes |
All other actions (http.request, docker.run, etc.) and inline run: steps | No (validation error) |
Setting worker_selector on an unsupported action produces a validation error.
Routing Each Parallel Item to Its Own Worker
A step-level worker_selector resolves per child run on a parallel step, with the item available as ${ITEM}, so one fan-out can pin each item to a different worker:
steps:
- id: drain
action: dag.run
with:
dag: drain-host
params:
mode: safe
worker_selector:
host: ${ITEM}
parallel:
items: [server-a, server-b, server-c]Items that resolve to identical child parameters and differ only by selector still become separate child runs, one per item.
worker_selector: local
Setting worker_selector to the string "local" (case-insensitive) forces the DAG to run on the main instance, regardless of the default_execution_mode setting. This sets ForceLocal=true in the dispatch decision.
worker_selector: local
steps:
- run: curl -f http://localhost:8080/healthThe string "local" is the only allowed string value for worker_selector. Any other string value produces a validation error.
Example: GPU/CPU Routing
Workers:
# GPU worker
dagu worker --worker.labels gpu=true,cuda=12.0
# CPU worker
dagu worker --worker.labels cpu-optimized=true,cores=64DAG with both DAG-level and step-level selectors:
# Parent DAG: runs on any worker (or locally)
steps:
# Dispatched to a GPU worker
- action: dag.run
with:
dag: train-model
worker_selector:
gpu: "true"
# Dispatched to a CPU worker
- action: dag.run
with:
dag: aggregate-results
worker_selector:
cpu-optimized: "true"
---
name: train-model
worker_selector:
gpu: "true"
tools:
- astral-sh/uv@0.11.14
steps:
- run: uv run --python 3.13.9 python train.py
---
name: aggregate-results
worker_selector:
cpu-optimized: "true"
tools:
- astral-sh/uv@0.11.14
steps:
- run: uv run --python 3.13.9 python aggregate.pyThe parent DAG's dispatch decision and each child's dispatch decision are evaluated independently. See Distributed Execution - Sub-DAG Dispatch for details.
Example: Desktop Workers
Computer steps operate the desktop of the worker that runs them. Run a worker in the logged-in session of each desktop host, check the host with dagu computer check, and label the worker:
# On the Windows host, in the user's session
dagu computer check
dagu worker --worker.labels desktop=financeRoute computer DAGs with a DAG-level selector; a step-level worker_selector on computer.run is a validation error:
worker_selector:
desktop: finance
llm:
provider: anthropic
model: claude-opus-5
steps:
- id: post
action: computer.run
with:
do:
- act: Post invoice INV-0001 in the ERP client
