Ditch Airflow
Most teams running Airflow maintain a Python framework in order to accomplish 'run this every morning'. There is a shorter path.
Airflow won because it was the first credible open-source scheduler with a real dependency graph, back when the alternative was cron and hope. It earned that.
It is also the tool teams complain about most, and the complaints repeat. You maintain a Python application in order to schedule work. Upgrades break DAGs. Dependency conflicts between the scheduler environment and your task code turn into their own project. Local development does not resemble production. A job that is conceptually one line takes a file of boilerplate. If you escaped to a managed offering, you now pay for the privilege of still writing DAGs.
When your orchestration is mostly data integration, that is a lot of framework for very little.
What replaces it
Flows are built by dragging. Sources, destinations, transformations, and dependencies are configuration, and the scheduler ships with the platform instead of being a service you run. Notifications, webhooks, and listeners are included. No executor to size, no metadata database to vacuum.
Control flow is where people expect a visual tool to collapse, so here is the detail. Nested flows and Composer, our visual flow builder, support four post-step actions: continue, Go to step, Dynamic goto, and End. Dynamic goto computes the target step name in JavaScript or Python at runtime. Every action can be guarded by a condition. Combined with conditional execution, which decides whether a step runs at all, and looping, which iterates inside a step, that covers the branching people actually build.
Code stays available. JavaScript, Python, and SQL run inline, and external commands run as steps. Code becomes an option for the parts that need it rather than the entry fee for the parts that do not.
The operational half
This usually decides the comparison, because writing a scheduler is easy and running one is not.
Flow executions suspend and resume, and the suspension survives a restart. In the UI that is Settings โ Flows โ Suspend flow executions with Keep suspended after restart until resumed manually. From the host it is suspend-flows, flow-suspend-status, and resume-flows, which operate on the Redis-backed flag directly and therefore work while Tomcat is stopped. During a restore Tomcat is stopped, which is precisely when a schedule firing does the most damage. Persistent suspend is shared across nodes through Redis.
Flows get inspected automatically. The Inspect Flow button runs in the background when a flow loads and again on any change, including changes to linked connections and formats, and it colors to the highest severity found. Findings from every run aggregate into a dashboard with severity, root cause, and suggested fixes.
Backup and restore are commands. The host CLI covers PostgreSQL, Redis, and app.data across native, Docker, and multi-node deployments, with parity between etlworks-cli.sh on Linux and etlworks-cli.ps1 on Windows.
Where Airflow still wins
Airflow is a general-purpose orchestrator, and that matters when your graph is not mostly data movement. Sequencing dbt runs, arbitrary containers, ML training, and a dozen internal services under one scheduler is what it is for. Same answer if your team's advantage is Python and you would rather own everything as code.
We orchestrate data integration. Inside that scope the platform does the whole job: connectors, mappings, CDC, and the schedule. Outside it, we are a step in someone else's graph, and there is a REST API and a CLI for exactly that.
The question worth asking before a migration is how much of your DAG count is orchestration logic and how much is glue around extracts and loads. For most teams we talk to, it is mostly glue.