Dagu: a single-binary workflow orchestrator for teams whose main work is not orchestration
Self-hostable workflow orchestrator for teams whose main work isn't orchestration. Declarative YAML over your scripts, SSH commands, containers, etc; keep workflows separate from business logic. One binary, no database, runs on limited H/W resources. Alternative to Airflow / Cron / Job Scheduler.
At a glance
- What is it?
- Dagu keeps workflow structure in YAML and leaves your scripts untouched. It installs as one binary with a built-in Web UI and no external database, which is exactly why it fits small operations teams and why it is the wrong pick for heavy, code-defined data platforms.
- Who is it for?
- Adopt Dagu if you already have working scripts and containers and want scheduling, retries, dependencies, run history and a Web UI without operating a metadata database or a message broker. Skip it if your pipelines are written as Python framework code with heavy dynamic task generation, or if you need a hosted control plane rather than something you run yourself.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Dagu solves: cron with no memory, Airflow with a platform attached
The README frames the audience bluntly: teams whose main work is not orchestration. You have scripts and containers that already run. What is missing is a schedule, dependency ordering, retries, and one place to read logs. Cron gives you the schedule and nothing else. Airflow gives you the rest, but the README's own comparison says you then operate a scheduler, a metadata database, workers and a Python environment, and your jobs get rewritten as @dag/@task framework code. Temporal is described the same way: durable execution, but your business logic moves into its SDK and programming model.
Dagu's answer is that workflow structure is configuration, not code. Order, dependencies, retries, schedules and human tasks live in one YAML file next to your scripts. The README states the scripts never import the orchestrator: delete the YAML and they run exactly as before. That property is the whole pitch, and it is a real constraint on design rather than a slogan. Anything that would require your script to know about Dagu has been pushed out of the script and into the YAML.
The intended users are operations and internal automation teams: ETL and data operations, legacy scheduled jobs, media conversion with ffmpeg, infrastructure automation over SSH, GitHub-triggered workflows on private infrastructure, container and Kubernetes steps, customer support self-service, and IoT or edge jobs. The common thread is that the work already exists as commands, and the missing piece is the wrapper around it.
How Dagu runs a workflow: one process, file-backed state, DAGs in YAML
Dagu is a single Go binary. The README states there is no external DBMS and no message broker, and that it runs on Linux, macOS and Windows. The README's own diagram contrasts a traditional orchestrator (web server, scheduler, workers, PostgreSQL, Redis or RabbitMQ, Python runtime, described as 6+ services) with a single command, dagu start-all.
State lives in local files. The README's performance section says Dagu stores state in local files and reaches production throughput without external services, and that a single machine can run thousands of workflow runs per day with actual capacity depending on CPU, memory, disk and workflow shape. That file-backed design is also what the media-conversion use case leans on: workers can run heavy transcodes in parallel without a database becoming the bottleneck.
Workflow definitions are declarative YAML describing a DAG. Steps can be shell commands, Docker containers, Kubernetes Jobs, or remote commands over SSH, run through what the project calls Dagu Actions. Sub-DAGs let you compose reusable pieces, and concurrency controls bound how much runs at once. Scheduling uses cron syntax with timezones, overlap policies and catch-up windows, so a missed window is a decision you make in config rather than a silent gap.
Scale-out is described as spreading execution across machines when one node is not enough. The README does not describe the coordination mechanism between workers in the text available here, so treat multi-node deployment as something to read up on in the docs before you plan around it. The repository does ship a charts/ directory and a helm-dagu-2.0.4 release, which indicates Kubernetes deployment is a supported path.
There is also a built-in MCP server, described as being for inspecting workflows and runs, maintaining Wiki pages, applying changes, and controlling runs. That is a notable design choice: the control surface exposed to agents is the same one humans use in the UI.
Installing Dagu and running a first workflow
The README lists several install paths. On macOS and Linux the installer script is the shortest route:
curl -fsSL https://raw.githubusercontent.com/dagucloud/dagu/main/scripts/installer.sh | bashHomebrew and npm are also documented, and Windows uses a PowerShell installer:
brew install dagu
npm install -g --ignore-scripts=false @dagucloud/daguirm https://raw.githubusercontent.com/dagucloud/dagu/main/scripts/installer.ps1 | iexIf you prefer containers, the README gives a Docker invocation that mounts a host directory for state and publishes the UI port:
docker run --rm -v ~/.dagu:/var/lib/dagu -p 8080:8080 ghcr.io/dagucloud/dagu:latest dagu start-allThe README adds a caveat directly under that command: it does not expose the host Docker daemon. If your workflow steps are Docker containers rather than shell commands, that mount is the first thing you will need to address, because container steps cannot reach a daemon that was never mounted in.
Starting the whole stack is one command, dagu start-all, which brings up the scheduler and the Web UI together. The live demo referenced in the README uses demouser as both username and password, which tells you the default credential shape is simple and that you should not leave an internet-facing instance on defaults.
The README points to docs.dagu.sh/getting-started/cli for CLI usage and to examples/ in the repository for workflow definitions. The README itself does not inline a complete YAML example, so the first real step after install is reading those examples rather than improvising a schema. There is a README_SCHEMA.md and a schemas/ directory in the repository root, and an api/v1/api.yaml OpenAPI document referenced from the README, which is where you would look to confirm field names before writing anything non-trivial.
Where Dagu stops being the right tool
The honest limitation is the flip side of the design. Because workflow structure is configuration, anything that needs to be computed at definition time is awkward. If your DAG is generated per customer, per partition or per model run, and the shape of the graph depends on data that only exists at runtime, a YAML-first engine makes you either template the YAML or move that logic into a step. Airflow's Python-defined DAGs exist precisely because that dynamic case is common in data engineering. Dagu is not aimed at it.
The second boundary is durability semantics. The topics list includes durable-execution, but the README's own comparison puts Temporal in a different category: Temporal moves business logic into its SDK and programming model, and in exchange you get execution guarantees that survive process death mid-step. Dagu's retries and run history are around the workflow and its steps; a long-running step that dies is a step that failed, not a computation that resumes from where it stopped. If your requirement is exactly-once side effects across crashes, that is a different product category.
Third, the Docker caveat above is a genuine operational trap. The documented run command does not mount the host Docker socket, so container-based steps will not work out of the box in that configuration. You either mount the socket (and accept the security implications of doing so) or run Dagu directly on the host.
Fourth, file-backed state is a trade-off, not a free win. It removes the database dependency, but it also means state is tied to the filesystem it lives on. The README does not document backup or migration procedures for that state, so if you are planning disaster recovery, that is a gap you need to close from the docs before you rely on it.
Dagu compared with Airflow and Temporal, on approach rather than features
The difference with Airflow is where the workflow lives. In Airflow the DAG is Python that imports the framework; the framework is a dependency of your pipeline definition. In Dagu the DAG is YAML that references your scripts; the orchestrator is not a dependency of anything you wrote. That changes who can edit a workflow. A YAML file with a schedule and a list of commands is editable by someone who does not write Python, and the README explicitly targets non-engineering self-service use cases for that reason. The cost is expressiveness: Airflow can compute a graph, Dagu describes one.
The difference with Temporal is where the execution guarantees live. Temporal's model is that your code runs inside its SDK so the runtime can replay and resume it. Dagu's model is that your code runs as a subprocess, container or SSH command, and Dagu records the outcome. You keep your code exactly as it is, and in return you get observability and retry semantics rather than durable execution of the code itself. Neither is better in the abstract; they answer different questions.
The difference with cron is the one most readers will actually feel. Cron has no dependency graph, no retries, no history and no UI. Dagu's README states the contrast directly, and the practical consequence is that a failing nightly job stops being silent.
Against Kubernetes-native scheduling, the difference is the unit of work. A Kubernetes Job is one container run; Dagu composes many steps, of which some may be Kubernetes Jobs, into a graph with ordering and retries. The repository ships charts/, so the two are meant to be used together rather than as substitutes.
Maintenance, releases and the GPL-3.0 question
The repository is not archived. The last push was on 2026-09-09, and the most recent releases are v2.16.3 on 2026-09-09, helm-dagu-2.0.4 on 2026-09-09, and v2.16.2 on 2026-09-02. Release cadence in the recent window is frequent, with patch releases days apart, and a Helm chart released alongside the application.
Upgrade cost is shaped by the no-database design. There is no schema migration against a live PostgreSQL instance to coordinate, but the repository does contain SCHEMA_MIGRATION.md and a schemas/ directory, which suggests the on-disk state and the workflow schema do evolve and have documented migration paths. Read those before upgrading across minor versions rather than assuming a drop-in replacement.
Licensing is GPL-3.0, and the repository root contains both LICENSE and LICENSING.md. The presence of a separate LICENSING.md usually indicates the project distinguishes between components or between the application and its dependencies, and go.mod pulls in a long list of third-party modules including cloud SDKs for AWS, Azure, Google Cloud and Alibaba Cloud secret managers. If you are embedding Dagu in a product you distribute, the copyleft terms and any component-level exceptions in LICENSING.md are what you need to read. This is not legal advice; read the files and get your own review if distribution is on the table. Running Dagu internally to schedule your own jobs is the ordinary case the project is built for.
The dependency list is worth noting for a different reason: it is large. A single binary is the deployment story, but it is not a small binary, and the build in the Dockerfile compiles with CGO_ENABLED=1 and static linking flags, which is why the image installs g++ in the build stage.
Editorial conclusion
Adopt Dagu if you already have working scripts and containers and want scheduling, retries, dependencies, run history and a Web UI without operating a metadata database or a message broker. Skip it if your pipelines are written as Python framework code with heavy dynamic task generation, or if you need a hosted control plane rather than something you run yourself. Before committing, verify two things on your own hardware: that the concurrency and queue limits you set behave the way your workload needs, and that the GPL-3.0 and LICENSING.md terms fit how you intend to distribute anything built on top of it.
Frequently asked questions
What is Dagu?
Dagu is a self-hostable workflow orchestrator written in Go. It defines DAGs in declarative YAML and runs shell commands, Docker containers, Kubernetes Jobs and SSH commands as steps, with a built-in Web UI, no external database and no message broker.
What does Dagu mean in Chinese?
The repository does not state a meaning or translation for the name. The README uses Dagu only as the project name, so any Chinese meaning would have to come from outside this material.
How do I install Dagu on macOS or Linux?
The README gives an installer script for macOS and Linux, a Homebrew formula, an npm package, a PowerShell installer for Windows, and a Docker image at ghcr.io/dagucloud/dagu:latest. Starting the scheduler and Web UI together is done with dagu start-all.
Does Dagu need a database?
No. The README states Dagu is self-contained with no external DBMS or message broker required, and that it stores state in local files. That file-backed state is also what the media-conversion use case relies on for parallel workers.
What licence does Dagu use?
The project is licensed under GPL-3.0, and the repository root contains both LICENSE and LICENSING.md. The separate LICENSING.md is worth reading if you plan to distribute something built on top of Dagu.
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/dagucloud-dagu)