Maintaining and automating data workloads · Topic 2 of 5

Cloud Composer DAGs and Repeatable Scheduling

Write Cloud Composer DAGs with operators, sensors, retries and templated dates, make tasks idempotent for backfills, and pick a scheduler for each job.

  • 5 min
In a nutshell
  • A DAG is tasks plus dependencies; operators do work, sensors wait.
  • Use templated logical dates such as {{ ds }} so reruns process the right day.
  • Idempotent tasks make retries and backfills safe.

What it is

Cloud Composer is managed Apache Airflow. You describe a workflow as a directed acyclic graph (DAG) in Python: tasks, the order they run in, and when the whole graph starts. Repeatability means each run produces the same result for the same date, however many times it runs, so retries and backfills are safe.

Schedulecron or eventDAG runlogical dateTaskssensor, load, checkRetrieson failureSame resultevery rerun

How it works

DAG building blocks

ConceptMeaning
DAGThe workflow: tasks plus dependencies, with no cycles
OperatorA task type, such as BigQueryInsertJobOperator or a Dataflow or Dataproc operator
SensorA task that waits for a condition, such as a file in Cloud Storage
DependenciesSet with >>, for example extract >> load >> check
scheduleA cron expression or preset such as @daily
start_date and catchupWhen scheduling begins and whether missed past runs are created
retries and retry_delayAutomatic retries for transient failures
Templated dates such as {{ ds }}The run's logical date, so each run processes its own day

A DAG for a daily load

from datetime import datetime, timedelta
from airflow import DAG
from airflow.providers.google.cloud.sensors.gcs import GCSObjectExistenceSensor
from airflow.providers.google.cloud.operators.bigquery import (
    BigQueryCheckOperator, BigQueryInsertJobOperator)

with DAG(
    dag_id="daily_sales",
    start_date=datetime(2026, 1, 1),
    schedule="0 3 * * *",
    catchup=False,
    default_args={"retries": 2, "retry_delay": timedelta(minutes=5)},
) as dag:
    wait_for_file = GCSObjectExistenceSensor(
        task_id="wait_for_file",
        bucket="landing-bucket",
        object="sales/{{ ds }}/_SUCCESS",
        mode="reschedule",
    )
    load = BigQueryInsertJobOperator(
        task_id="load_partition",
        configuration={"query": {
            "query": "CALL sales.load_day('{{ ds }}')",
            "useLegacySql": False,
        }},
    )
    check = BigQueryCheckOperator(
        task_id="check_rows",
        sql="SELECT COUNT(*) > 0 FROM sales.daily WHERE sale_date = '{{ ds }}'",
        use_legacy_sql=False,
    )
    wait_for_file >> load >> check

The sensor runs in reschedule mode, so it frees its worker slot between checks. The check task fails the run if the day's partition is empty, which catches silent failures.

Making runs repeatable

PracticeWhy
Idempotent writes: overwrite the day's partition or MERGE on a keyA retry or rerun replaces data instead of duplicating it
Use the logical date, not "now"A rerun for 3 October processes 3 October, even if run later
Keep tasks small and single-purposeFailed steps retry alone
Let services do the heavy workComposer orchestrates; BigQuery, Dataflow and Dataproc process
Store DAGs in Git and deploy with CI/CDEvery environment runs the same tested code
Pass only small metadata between tasks (XCom)Large data belongs in Cloud Storage or BigQuery

Backfilling runs a DAG for past logical dates, for example after a bug fix. It is only safe when tasks are idempotent and use the templated date.

Exam tip

When a stem says "reruns create duplicate rows", the fix is idempotency: write with partition overwrite or MERGE. Adding more retries makes the problem worse.

Scheduling and orchestrating jobs in a repeatable way

NeedChoose
Many dependent tasks, sensors, backfillsCloud Composer
One SQL statement on a scheduleBigQuery scheduled query
SQL transformation graph in BigQueryDataform workflow configuration
A few API calls, serverlessWorkflows, started by Cloud Scheduler or Eventarc
A fixed sequence of Spark jobs on a temporary clusterDataproc workflow template
Start work when a file arrivesEvent trigger (Eventarc) or a sensor in a DAG

A worked example

A team's cron scripts on a VM run five steps each night. When one fails, someone reruns the rest by hand, and reruns double-load data. The engineer replaces the scripts with a Composer DAG.

A sensor waits for the day's success file, and each load writes to the logical date's partition with overwrite. A row-count check closes the DAG, and retries handle transient errors. The DAG lives in Git and deploys through CI, and missed days are backfilled without duplicates.

Cron scriptsmanual rerunsComposer DAGsensor, load, checkPartition overwriteby logical dateSafe retries and backfills

How the exam asks about this

  • "A workflow must wait for a file, run three dependent jobs and retry failures automatically." A Cloud Composer DAG with a sensor, operators and retries.
  • "Rerunning last week's DAG runs created duplicate rows." Make tasks idempotent with partition overwrite or MERGE keyed on the logical date.
  • "Only one SQL statement must run every hour." A BigQuery scheduled query, not a Composer environment.

What to remember for the exam

  • A DAG is tasks plus dependencies; operators do work, sensors wait.
  • Use templated logical dates such as {{ ds }} so reruns process the right day.
  • Idempotent tasks make retries and backfills safe.
  • Composer orchestrates; the data services do the processing.
  • Pick the lightest scheduler that meets the need.
Watch out

Using datetime.now() inside a task breaks repeatability. A rerun next week would process next week's data instead of the day it was meant for.

Common mistakes

Processing large data inside Airflow workers. Workers are for orchestration; push work to BigQuery, Dataflow or Dataproc.

Leaving catchup on with an old start date. Airflow schedules every missed run at once when the DAG is enabled.

Appending on every run. Retries then duplicate data; overwrite partitions or merge.

Check yourself

  • What does catchup control in an Airflow DAG?

    Whether Airflow creates runs for past schedule intervals between the start date and now when the DAG is enabled.

  • Why should a DAG task use the logical date instead of the current time?

    So that retries, reruns and backfills process the intended day and give the same result every time.

  • What is the benefit of a sensor in reschedule mode?

    It releases its worker slot between checks instead of occupying it while waiting.

Topic 2 of 5 in Maintaining and automating data workloads

Test yourself on Maintaining and automating data workloads

The full Google Cloud Professional Data Engineer question bank has 733 questions, with timed practice exams and an explanation for every answer.

This study guide is independent and is not affiliated with, endorsed by, or sponsored by Google Cloud. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.