DEV Community

Cover image for Cron is too dumb. Airflow is too heavy. Meet cronova.
Zoy
Zoy

Posted on

Cron is too dumb. Airflow is too heavy. Meet cronova.

A self-hosted workflow scheduler that fits in a single Go binary — DAGs, retries, backfill, a web console, and a built-in endpoint for AI agents. No JVM, no Python, no database to run.

📌 Originally published by the team at zoytown.com. cronova is a free, open-source (MIT) project — source, docs and releases are on GitHub: github.com/zoyluoblue/cronova.


Every team that runs scheduled jobs eventually hits the same wall.

You start with cron. It's perfect — until the day one job needs to run after another, or retry on failure, or backfill a week you missed, or just tell you why last night's run died. cron does none of that. So you start bolting on shell glue, lock files, and a Slack webhook, and six months later you've built a bad workflow engine by accident.

The "grown-up" answer is Apache Airflow. It's genuinely great — and it's also a Python stack, a Postgres, a Redis/Celery broker, and a small pile of YAML and Docker to keep alive. For a real data platform, worth it. For "I have a dozen jobs on one box," it's a second full-time system to babysit.

I wanted the middle: real DAG scheduling, none of the operational weight. That's cronova.

What cronova is

cronova is an open-source workflow scheduler / job orchestrator written in Go. It schedules DAGs — directed acyclic graphs of tasks — on cron or interval triggers, runs each task as an OS subprocess, and ships with a web console, a REST API, a CLI, and an MCP endpoint for AI agents.

The whole thing is one static binary with an embedded SQLite database. No JVM. No Python runtime. No external database. No message broker. No containers required. You install it with one command and you're done:

curl -fsSL https://raw.githubusercontent.com/zoyluoblue/cronova/main/deploy/bootstrap.sh | sudo bash
Enter fullscreen mode Exit fullscreen mode

That drops a native service under systemd (Linux) or launchd (macOS) and runs a short setup wizard. Upgrades are cronova update; removal is cronova uninstall. It manages its own lifecycle.

Your first DAG in 60 seconds

A DAG is a single YAML file. Drop this in ./dags/:

dag_id: daily_etl
schedule: "0 2 * * *"     # cron; or "@every 30s"; omit for manual-only
start_date: 2026-06-01
catchup: true             # backfill missed periods
default_retries: 2
tasks:
  - id: extract
    type: shell
    command: "python extract.py --date {{ logical_date }}"
  - id: transform
    command: "python transform.py --date {{ logical_date }}"
    deps: [extract]
  - id: load
    command: "psql -f load.sql"
    deps: [transform]
    retries: 3
    timeout: 1800
Enter fullscreen mode Exit fullscreen mode

Then:

cronova serve                 # scheduler + console at http://localhost:8090
cronova trigger daily_etl     # run it now
cronova runs daily_etl        # watch task states advance
Enter fullscreen mode Exit fullscreen mode

{{ logical_date }} is the run's logical date — the period it represents — which is what makes catchup meaningful: a backfilled run processes the data for that day, not wall-clock "now". The same values land in your process as CRONOVA_* environment variables, so your scripts can just read them.

The parts that make it feel finished

A web console that isn't an afterthought. Open http://localhost:8090 and you get a dashboard, run history with sparklines, a dependency graph, and live log tailing while a task runs.

cronova dashboard — self-hosted workflow scheduler

The task editor is the piece I'm proudest of. You don't type {{ }} template syntax — every variable is a color-coded pill you click or drag in from a grouped palette (built-in run variables, your shared variables, connections, and per-run params).

cronova task editor — drag-and-drop template variable pills

Polyglot tasks. Every task runs as a subprocess, so it can be shell, python, sql, a jar, or an http call — any language on the host. You can even drag-and-drop a whole project folder (or a .zip) into the console and point a task at it; each run gets a fresh, isolated copy as its working directory.

Crash-recoverable execution. Run tasks in the optional decoupled gRPC executor and you can restart — or upgrade — the scheduler without killing running jobs. On recovery it re-attaches to in-flight tasks, with no double execution.

It speaks Airflow's vocabulary. Dependencies, cron and interval schedules, cross-DAG triggers, catchup/backfill, per-task retries and timeouts, resource pools, and trigger rules — the primitives you already know.

The part nobody else ships: it's AI-native

cronova has a built-in Model Context Protocol (MCP) server. Point Claude (or any MCP client) at it and an AI agent can list, create, validate, trigger, and inspect DAGs — through the same token-authenticated, role-gated API a human uses, not a bolted-on hack.

cronova tokens create my-agent -role admin
cronova mcp                                   # MCP server over stdio
Enter fullscreen mode Exit fullscreen mode

There's also a remote JSON CLI for scripting:

export CRONOVA_SERVER=http://localhost:8090 CRONOVA_TOKEN=cnv_pat_…
cronova dags -o json
cronova api POST /api/dags/validate '{"dag_id":"x","tasks":[…]}'
Enter fullscreen mode Exit fullscreen mode

Where it fits (and where it doesn't)

cronova is for the sweet spot between a bare crontab and a full data platform: you want DAGs, retries, backfill, pools, a UI and an API — but not a stack to operate.

Being honest about the other end: if you need hundreds of provider integrations, a managed cloud offering, or Python-native dynamically-generated DAGs at massive scale, Airflow (or Dagster / Prefect) is still the richer choice. cronova deliberately trades that ecosystem for operational simplicity: one binary, YAML DAGs, tens of megabytes, Linux & macOS on amd64/arm64.

Try it

If it saves you from standing up an Airflow cluster for a handful of jobs, a ⭐ on GitHub genuinely helps other people find it.


cronova is an open-source project from the team behind *zoytown.com*. Built in Go, MIT-licensed. Questions and issues welcome on GitHub.

Top comments (0)