Why Apache Airflow Instead of Cron? A Deep Dive Into How Airflow Actually Schedules Your DAGs

작성자

카테고리:

← 피드로
DEV Community · Maithreyan · 2026-08-12 개발(SW)

“Why not just use a cron job?” is the first question I get whenever someone sees an Airflow DAG. Fair question. Cron works. It’s been around for decades. It’s simple.

The real answer isn’t that cron is bad — it’s that cron solves a different problem than Airflow does.

Cron is a job scheduler. It runs a command at a fixed time. That’s it. It doesn’t know whether the command succeeded, whether its dependencies are satisfied, or whether it should even run at all today. It just fires the command and moves on.

Airflow is a workflow orchestrator. It doesn’t just schedule tasks — it models them as a graph of dependencies, tracks their state, retries failed ones, and gives you a UI to see what ran, what failed, and why.

Here’s where that difference actually matters.

The problem cron can’t solve

Imagine a simple ETL pipeline:

  1. Extract raw data from an API
  2. Validate and clean it
  3. Load into a warehouse
  4. Run a transformation
  5. Send a Slack alert if anything fails

With cron, you’d write five separate cron entries, one per step, and hope the timing works out. If step 2 fails but step 3 runs anyway, you now have bad data in your warehouse. If step 4 takes twice as long one day, you’ve silently broken your SLA. Nobody gets notified unless you manually add alerting logic to every script.

With Airflow, you model this as a DAG:

from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime

with DAG(
    dag_id="daily_etl",
    schedule="0 6 * * *",
    start_date=datetime(2026, 1, 1),
    catchup=False,
) as dag:

    extract = PythonOperator(task_id="extract", python_callable=extract_data)
    validate = PythonOperator(task_id="validate", python_callable=validate_data)
    load = PythonOperator(task_id="load", python_callable=load_to_warehouse)
    transform = PythonOperator(task_id="transform", python_callable=run_transformation)

    extract >> validate >> load >> transform

Enter fullscreen mode Exit fullscreen mode

Airflow guarantees the order. If validate fails, load and transform never run. You get automatic retries, failure alerts, and a web UI that shows exactly where the pipeline broke and why.

How Airflow actually schedules a DAG

This is where it gets interesting. Airflow doesn’t just “run your Python script at a fixed time” the way cron does.

When you define a DAG with a schedule (or schedule_interval in older versions), Airflow doesn’t pass that cron expression directly to the OS scheduler. Instead, it converts it into a timetable — an internal object that determines when a DAG run should be created.

The scheduler process runs continuously, checking every few seconds whether any DAGs are ready to run based on their timetable. When a DAG is due, the scheduler creates a DagRun object for that execution date and queues up the tasks. The actual execution happens on worker processes (via the executor you’ve configured — Local, Celery, or Kubernetes), not directly from the scheduler itself.

This matters for two reasons:

1. Airflow schedules based on data intervals, not wall-clock time.

A DAG with schedule="0 6 * * *" (daily at 6 AM) doesn’t run at 6 AM to process data at that moment. It runs at 6 AM to process data for the previous interval — typically yesterday, if you’re on a daily schedule. Airflow’s execution_date is the start of the data interval, not the time the task actually runs.

This is why catchup=True (the default in older Airflow versions) can surprise you: if you deploy a new daily DAG on January 10th with a start date of January 1st, Airflow will immediately create DagRuns for every day from Jan 1–9 and try to backfill them all, because it thinks you’re behind on processing those intervals.

2. The scheduler is stateful and centralized.

Unlike cron, which runs independently on each machine, Airflow’s scheduler is a single process (or a small cluster in HA setups) that maintains a global view of all DAGs, their schedules, and their current state. It knows which tasks are running, which are queued, which have failed, and which are blocked by upstream dependencies. This is what enables features like automatic retries, SLA monitoring, and the ability to pause or unpause a DAG from the UI without touching the server.

The part that actually matters in production

The real difference isn’t features — it’s what happens when things go wrong.

Cron jobs fail silently. Logs are scattered across servers. Backfilling a missed run means manually re-running scripts in the right order. Scaling to 50+ pipelines means managing hundreds of crontab entries across multiple machines, with no central visibility into what’s running or what’s broken.

Airflow tracks everything — task state, execution history, retry counts, SLAs. You can backfill a date range with one command. You can see which tasks are blocking others. You can add sensors that wait for external data to arrive before starting a downstream task. None of this exists in cron; you’d have to build it yourself, and you’d build it worse than Airflow already has.

I’ve seen this play out directly: a team running 30+ cron-based ETL scripts had no idea when a critical pipeline silently failed for three days because the script exited with a 0 status code even though the data was stale. Moving to Airflow meant that same pipeline would have automatically retried, alerted on failure, and shown up in red on a dashboard — impossible to miss.

When cron is actually the right choice

I’m not saying “never use cron.” Cron is perfect for:

  • Simple, independent tasks (daily backups, log rotation, health checks)
  • Small-scale automation (fewer than ~5 scripts, no dependencies between them)
  • Situations where silent failure is acceptable or you have other monitoring in place

If your pipeline is “run this one script at 2 AM and that’s it,” cron is fine. If your pipeline has dependencies, retries, alerts, or cross-team visibility needs, Airflow pays for itself quickly.

The takeaway

Cron tells a task when to run. Airflow decides what should run, in which order, and what happens if something fails.

That difference becomes critical the moment your workflows grow beyond “one script, one schedule.”

Do you still use cron for anything in production, or has everything moved to an orchestrator?

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다