Back to docs
Getting Started

Local Development

Dagy executes flows in-process by default when `DAGY_API_URL` is not set. If `DAGY_API_URL` is set, runs will be sent to the remote API instead.

Local execution

Dagy executes flows in-process by default when DAGY_API_URL is not set. If DAGY_API_URL is set, runs will be sent to the remote API instead.

Local execution contract

  • Inputs are hydrated from upstream task outputs before invocation.
  • Outputs are captured and stored as artifacts under .dagy/artifacts/<run_id>/<task_id>/.
  • Outputs must be JSON-serializable by default; use LocalArtifact for text or file outputs.
  • Task states: RUNNING -> SUCCEEDED | FAILED | SKIPPED.
  • Retries and timeouts use the task's configured policy.

Local configuration

  • DAGY_LOCAL_DIR (default: ~/.dagy)
  • DAGY_LOCAL_VERBOSE (default: false)
  • DAGY_LOCAL_ARTIFACT_MAX_BYTES (default: 5242880)

See .env.example for a ready-to-copy local configuration.

Local metadata storage

Run metadata is stored in DuckDB at ~/.dagy/dagy.duckdb and mirrored as JSON under ~/.dagy/runs/<run_id>/.

Running locally (SDK)

from dagy import flow, task

@task
def step() -> str:
    return "ok"

@flow
def my_flow():
    return step()

result = my_flow.run_local(max_workers=2, fail_fast=True)
print(result.run_id, result.status)

Running locally (CLI)

dagy run path/to/flow.py:my_flow

Inspecting runs and logs

dagy runs list
dagy runs show <run_id>
dagy logs <run_id>
dagy logs <run_id> --task <task_run_id>

Hot reload / fast iteration

  • Keep the flow file small and runnable as a module.
  • Use dagy run to re-run quickly after edits.
  • Prefer max_workers=1 for deterministic step-by-step debugging.