Practice — Airflow & Workflow Orchestration (6 questions)
A New DAG Silently Reprocessed a Year of History Permalink →
Your team ships a new DAG to populate a daily_revenue_snapshot table
from an internal billing API:
from datetime import datetime, timedelta
from airflow.decorators import dag, task
@dag(
dag_id="daily_revenue_snapshot",
schedule="0 7 * * *",
start_date=datetime(2025, 1, 1),
default_args={"retries": 2, "retry_delay": timedelta(minutes=5)},
)
def daily_revenue_snapshot():
@task
def pull_revenue(data_interval_start=None) -> str:
return _call_billing_api(data_interval_start) # rate-limited, 500 req/day
@task
def write_snapshot(payload: str, data_interval_start=None) -> None:
_insert_snapshot_row(payload, data_interval_start)
write_snapshot(pull_revenue())
daily_revenue_snapshot()
The moment this DAG is deployed and turned on (in mid-2026), roughly
540 DAG runs fire back to back within the hour. The billing API's
rate limiter starts rejecting requests, several write_snapshot calls
partially succeed after retries, and the daily_revenue_snapshot
table ends up with duplicate rows for a number of historical dates.
- Identify the exact configuration decision that caused ~540 runs to fire immediately, and explain the mechanism.
- The table also has duplicate rows for several dates — explain why, connecting it to a second, independent problem in this DAG beyond the one in part 1.
- Rewrite the DAG to fix both problems, and describe how you would still get the desired one year of history populated, safely.
Share this question
The Airflow UI Is Getting Slower Every Week — And So Is the Scheduler
Unlock this question →The DAG Run Labeled 'Jan 15' Doesn't Run On Jan 15 Permalink →
A daily DAG is scheduled schedule="0 7 * * *". An engineer writes a
task that emails "here is the {{ ds }} sales report," assuming
{{ ds }} will render as "today's date" — the day the email actually
goes out. They're confused when the run that fires on the morning of
January 16 renders {{ ds }} as 2026-01-15, and the report it
generates only contains data through the end of January 15, nothing
from January 16.
Nothing is broken. What does {{ ds }} — and the DAG run's
logical/execution date more generally — actually represent?
Share this question