First 50 of 200 questions. Each one lists the choices, the correct answer, and an explanation. The checker at the top of this page saves progress in this browser when it is available.
Continue in the practice tool above to load more questions, 50 at a time.
Question 1DAG fundamentals and structure
In an Airflow DAG file, what does the schedule parameter of the DAG object primarily define?
- The order in which tasks inside the DAG execute
- The maximum runtime allowed for a single task instance
- The number of worker slots reserved for each task
- The interval at which new runs are created for the DAG Correct answer.
Explanation
The schedule argument controls when the scheduler creates new DAG runs, accepting presets, cron expressions, timedeltas, or None. It has no effect on task ordering or resource allocation, which are governed by dependencies and executor configuration.
Question 2DAG fundamentals and structure
A data engineer wants two tasks to run at the same time with no ordering constraint between them. How should the DAG be written?
- Set the DAG's max_active_tasks to two and chain the tasks
- Add both tasks without any dependency operators between them Correct answer.
- Chain them with the right-bitshift operator so they run concurrently
- Wrap both tasks inside a single TaskGroup to force parallel execution
Explanation
Tasks with no upstream or downstream relationship are independent, so the scheduler may run them concurrently subject to pool and parallelism limits. Adding a dependency operator would impose ordering, and a TaskGroup only groups tasks visually and organizationally.
Question 3DAG fundamentals and structure
Which file naming rule must a Python file satisfy for Airflow to parse it as a DAG file by default?
- It must be placed in the plugins directory
- It must contain the substring dag or airflow in its name Correct answer.
- It must be named exactly dags.py
- It must declare a variable named dag_file at module level
Explanation
Airflow's default DAG discovery pattern matches files whose names contain dag or airflow, and only scans configured DAG folders. Files outside those folders or without a matching name are not parsed as DAG definitions.
Question 4DAG fundamentals and structure
What is the purpose of the catchup parameter on a DAG?
- It controls whether the DAG appears in the user interface
- It controls whether the scheduler creates runs for past intervals Correct answer.
- It controls whether failed tasks are retried automatically
- It controls whether task logs are written to remote storage
Explanation
With catchup enabled, the scheduler backfills runs for every completed interval between the start date and the present. Setting catchup to False limits scheduling to the current interval, which is useful for DAGs that should not process historical data.
Question 5DAG fundamentals and structure
Which object is used to declare a task that executes a Python function inside a DAG?
- DAGOperator
- PythonOperator Correct answer.
- FunctionHook
- TaskInstance
Explanation
PythonOperator wraps a callable and runs it when the task executes, accepting the function through the python_callable argument. Hooks are for connecting to external systems, and TaskInstance represents a single run of a task rather than a definition.
Question 6DAG fundamentals and structure
What does the start_date argument of a DAG represent?
- The creation time of the DAG file on disk
- The anchor from which the scheduler computes schedule intervals Correct answer.
- The deadline by which all tasks must finish
- The earliest timestamp at which a running task may begin
Explanation
The start_date anchors schedule computation; the scheduler creates runs for intervals that begin at or after that point. It is not a runtime deadline or a per-task start gate, and it is distinct from the file's modification time.
Question 7DAG fundamentals and structure
Which statement about the DAG identifier passed as the first argument to the DAG constructor is correct?
- It must be unique among DAGs known to the deployment Correct answer.
- It must match the name of the Python file
- It may be reused freely as long as the owners differ
- It is optional and defaults to the module name
Explanation
The dag_id is the primary key identifying a DAG in the metadata database, so two DAGs sharing an identifier will conflict. It is required and does not need to match the file name, though matching is a common convention.
Question 8DAG fundamentals and structure
A DAG defines tasks A, B, and C with A >> B and A >> C, and a fourth task D with B >> D and C >> D. Which task can start only after both B and C succeed?
- Task B
- Task C
- Task D Correct answer.
- Task A
Explanation
Task D has two upstream dependencies, B and C, so the scheduler will not run it until both upstream tasks have succeeded. A is the root task with no upstream dependencies, and B and C each depend only on A.
Question 9DAG fundamentals and structure
Which construct lets an author define a DAG's tasks and dependencies inside a function that can be called with different parameters to generate multiple DAGs?
- A DAG factory function Correct answer.
- A trigger rule setting
- A sensor with poke mode
- A custom hook class
Explanation
A factory function accepts parameters and returns a DAG object, allowing many similar DAGs to be generated from one code template. Hooks and sensors relate to interacting with external systems, and trigger rules only affect when a task runs relative to its upstream states.
Question 10DAG fundamentals and structure
What is the effect of setting max_active_runs on a DAG?
- It caps how many concurrent DAG runs the scheduler allows Correct answer.
- It sets the retry count for every task in the DAG
- It defines how long a run may stay in the running state
- It caps how many tasks a single run may execute
Explanation
max_active_runs limits concurrent DAG runs, which is important for DAGs that must not overlap when processing the same data. Task-level concurrency is controlled by max_active_tasks, and retries are set per task.
Question 11DAG fundamentals and structure
An author writes a DAG file where the DAG object is created inside a conditional block that is False during parsing. What happens?
- No DAG is registered because the object is never instantiated Correct answer.
- Airflow raises a parse error and pauses the whole deployment
- The DAG registers with an empty task list
- The scheduler creates the DAG using defaults from the previous parse
Explanation
DAGs are discovered by executing the file and collecting DAG objects created at module level, so conditional logic that skips instantiation yields no DAG. The file itself still parses without error, so no deployment-wide failure occurs.
Question 12DAG fundamentals and structure
Which practice keeps a DAG file's top-level code fast during scheduler parsing?
- Load all input files when the module is imported
- Run the query at module level to cache results
- Open a connection in the DAG constructor
- Keep heavy database queries inside the callable of a task Correct answer.
Explanation
The scheduler parses DAG files frequently, so top-level code should be limited to DAG construction. Expensive work such as queries or file reads belongs inside task callables so it runs only when the task executes.
Question 13DAG fundamentals and structure
A DAG uses a cron expression of 0 6 * * * with a start_date in the past and catchup disabled. What does the scheduler do?
- It refuses to schedule because past intervals were skipped
- It schedules only the most recent eligible interval, not the full history Correct answer.
- It runs the DAG continuously until the backlog clears
- It backfills every missed 6 a.m. interval since the start date
Explanation
With catchup disabled, the scheduler creates runs only for the current or most recent interval rather than every historical interval. Historical intervals are simply not scheduled, and the DAG still runs normally going forward.
Question 14DAG fundamentals and structure
What is the role of the default_args dictionary when passed to a DAG?
- It declares global variables shared across all DAGs
- It registers connections for external systems
- It supplies default settings inherited by tasks in that DAG Correct answer.
- It defines the executor used by the scheduler
Explanation
default_args provides fallback values such as retries, owner, and email that tasks inherit unless overridden. It is scoped to the DAG receiving it and does not configure executors or connections.
Question 15DAG fundamentals and structure
An author needs a task to run only after all upstream tasks have finished regardless of whether they succeeded or failed. Which trigger rule fits?
- all_done Correct answer.
- none_failed_min_one_success
- one_success
- all_success
Explanation
The all_done trigger rule fires once every upstream task has reached a terminal state, whether success or failure. all_success requires every upstream task to succeed, and one_success requires only a single success.
Question 16DAG fundamentals and structure
How does the TaskFlow API reduce boilerplate compared with classic operator-based DAGs?
- It stores task outputs permanently in the DAG file
- Task dependencies are inferred from how function return values are passed Correct answer.
- It executes tasks without involving the scheduler
- It removes the need to define a DAG object entirely
Explanation
With the TaskFlow API, decorated functions pass data through return values and arguments, and Airflow infers the resulting dependencies automatically. A DAG context is still required, and scheduling still goes through the normal scheduler.
Question 17DAG fundamentals and structure
Which argument on the DAG object determines how many task instances of that DAG may run concurrently?
- max_active_runs
- retries
- schedule_interval
- max_active_tasks Correct answer.
Explanation
max_active_tasks caps the number of task instances running at once within a DAG. max_active_runs instead limits concurrent DAG runs, and retries and schedule_interval govern retry behavior and timing.
Question 18DAG fundamentals and structure
A team wants shared default arguments applied consistently to every DAG in a project without editing each file. Which approach fits best?
- Set the defaults in the airflow.cfg scheduler section
- Define a shared helper module that builds DAGs with common defaults Correct answer.
- Copy the defaults into each DAG file manually
- Rely on task-level defaults provided by the executor
Explanation
Centralizing DAG construction in a shared helper module lets every DAG inherit the same defaults from one place. Airflow configuration and executors do not supply per-DAG default_args, and manual copying invites drift.
Question 19DAG fundamentals and structure
An author sets a DAG's start_date to a fixed timestamp and schedule to a timedelta of one day, then enables catchup. What does the scheduler do on first deployment?
- It creates one run per daily interval from the start date to now Correct answer.
- It creates runs only for intervals that contain task failures
- It waits one full day before creating any run
- It creates a single run for the current day only
Explanation
Catchup with a past start_date causes the scheduler to create a run for each completed interval between the start date and the present. Disabling catchup would limit scheduling to the latest interval, and runs are not conditioned on prior failures.
Question 20DAG fundamentals and structure
A DAG file imports a module that performs a network call at import time. Why is this a problem for the scheduler?
- The call executes inside the worker rather than the scheduler
- The import fails because DAG files forbid third-party modules
- The call repeats on every parse, delaying DAG processing across the deployment Correct answer.
- The call runs only once, so later parses use stale data
Explanation
DAG files are parsed repeatedly, so import-time side effects such as network calls recur and slow parsing for all DAGs in the folder. Side effects should be deferred into task callables so they run only at execution time.
Question 21DAG fundamentals and structure
Two DAG files in the same folder define DAGs with the same dag_id but different tasks. What is the likely outcome?
- The scheduler renames one DAG automatically to avoid conflict
- Airflow merges the tasks from both files into one DAG
- Both DAGs run independently under separate identifiers
- The definitions conflict, and the registered DAG reflects only one file's version Correct answer.
Explanation
The dag_id is the unique key for a DAG, so duplicate identifiers collide and only one definition is registered, with the winner depending on parse order. Airflow does not merge tasks or rename identifiers automatically.
Question 22DAG fundamentals and structure
A DAG must never have overlapping runs because each run rewrites the same partition. Which setting combination enforces this?
- catchup set to True
- max_active_tasks set to one
- max_active_runs set to one Correct answer.
- retries set to zero
Explanation
Setting max_active_runs to one ensures the scheduler will not start a new run while a previous one is still active. max_active_tasks limits tasks within a run, and catchup or retries do not prevent overlap.
Question 23DAG fundamentals and structure
What happens to a task whose upstream task is skipped when the default trigger rule applies?
- The downstream task runs normally
- The downstream task is skipped as well Correct answer.
- The downstream task waits indefinitely
- The downstream task fails with an error
Explanation
The default trigger rule all_success treats a skipped upstream task as not successful, so the downstream task is skipped too. Authors who want the downstream to proceed must choose a rule such as all_done or none_failed.
Question 24DAG fundamentals and structure
Which statement about the DAG context manager syntax is accurate?
- Tasks defined inside the with block are attached to that DAG automatically Correct answer.
- Tasks inside the block must still pass dag= to every operator
- Only one task may be defined inside the block
- The with block replaces the need for a schedule parameter
Explanation
Using with DAG(...) as dag: sets an active DAG context so operators created inside the block bind to it without an explicit dag argument. The schedule still comes from the DAG constructor, and any number of tasks may be defined.
Question 25Operators and task construction
In Airflow, which Python callable is used to attach a function to a DAG as a task without instantiating an operator class directly?
- @asset decorator
- @setup decorator
- @task decorator Correct answer.
- @dag decorator
Explanation
The TaskFlow API exposes the @task decorator, which wraps a plain Python function and converts it into a task when the DAG is parsed. The decorated function is invoked inside a DAG context to produce an operator instance. The @dag decorator instead marks a function as a DAG factory.
Question 26Operators and task construction
Which parameter of the PythonOperator specifies the callable that the task executes?
- op_kwargs
- python_callable Correct answer.
- provide_context
- executor_config
Explanation
The PythonOperator requires python_callable, which receives the function object to run at execution time. Arguments for that callable are supplied through op_args and op_kwargs. The provide_context flag only controls whether context variables are passed in.
Question 27Operators and task construction
What is the effect of setting depends_on_past=True on a task?
- It skips the task when the DAG is paused
- It waits for the previous scheduled run of that same task to succeed Correct answer.
- It triggers the task only on manual runs
- It waits for all upstream tasks in the current run to succeed
Explanation
depends_on_past creates a dependency across time: the task instance for the current logical date requires the prior logical date's instance of the same task to have succeeded. It does not change dependencies within the current run. This is commonly used for incremental processing that must proceed in order.
Question 28Operators and task construction
A task uses PythonOperator with op_args=[1, 2] and op_kwargs={'scale': 3}. How is the callable invoked?
- callable(1, 2, scale=3) Correct answer.
- callable(op_args=[1, 2], op_kwargs={'scale': 3})
- callable([1, 2], {'scale': 3})
- callable(scale=3, 1, 2)
Explanation
op_args is expanded as positional arguments and op_kwargs as keyword arguments when the operator calls the Python callable. The two lists are unpacked rather than passed as single objects. So the function receives two positional values and one keyword value.
Question 29Operators and task construction
Which operator is the standard choice for running a shell command as a task?
- BranchOperator
- BashOperator Correct answer.
- SSHOperator
- SubDagOperator
Explanation
BashOperator runs a command in a Bash shell on the worker and exposes the bash_command argument. It is intended for shell scripts and command-line tools. The SSHOperator runs commands on a remote host instead.
Question 30Operators and task construction
In a BashOperator, which argument lets a task receive the templated value of a previous task's XCom?
- env with a static dictionary
- output_encoding set to utf-8
- bash_command with a Jinja expression referencing task_instance.xcom_pull Correct answer.
- append_env set to True
Explanation
BashOperator templates its bash_command field, so Jinja expressions can call task_instance.xcom_pull to inject upstream values into the command string. The env parameter supplies environment variables but is not the templating mechanism. Templating must be enabled on the field, which bash_command already is.
Question 31Operators and task construction
What does the trigger_rule 'all_done' mean for a task?
- It runs only when every upstream task succeeded
- It runs once all upstream tasks have finished regardless of their state Correct answer.
- It runs only when all upstream tasks were skipped
- It runs when at least one upstream task failed
Explanation
trigger_rule determines when a task becomes eligible given the states of its upstream tasks. all_done makes the task run after every upstream task reaches a terminal state, whether success, failure, or skip. This is useful for cleanup tasks that must always execute.
Question 32Operators and task construction
A DAG has task A feeding tasks B and C. Which trigger rule should B use so it runs even if A fails?
- all_success
- none_failed
- all_done Correct answer.
- one_success
Explanation
all_done fires when all upstream tasks reach a terminal state, including failure, so B still runs after A fails. The default all_success would skip B when A fails. none_failed would also block because a failed upstream violates the rule.
Question 33Operators and task construction
Which operator returns a task ID that determines which downstream tasks are skipped?
- BranchPythonOperator Correct answer.
- PythonSensor
- TriggerDagRunOperator
- ShortCircuitOperator
Explanation
BranchPythonOperator calls a Python function whose return value is a task ID or list of task IDs; only those tasks proceed and the rest are skipped. ShortCircuitOperator instead returns a boolean that decides whether the whole downstream path continues. The distinction matters when only part of a branch should run.
Question 34Operators and task construction
What must a function used with BranchPythonOperator return?
- A task ID or list of task IDs to follow Correct answer.
- A DAG ID to trigger
- An XCom key to read
- A boolean indicating success
Explanation
The branch callable returns the task_id (or a list of task_ids) of the downstream tasks that should execute. All other downstream tasks are marked skipped. Returning a value that matches no downstream task causes an error at runtime.
Question 35Operators and task construction
Which construct groups related tasks visually and can carry shared default arguments in the UI?
- TaskGroup Correct answer.
- SubDagOperator
- DAG bundle
- Pool
Explanation
TaskGroup organizes tasks into a collapsible group in the UI and can hold default_args that apply to its members. It avoids the scheduler and performance problems associated with SubDagOperator. Groups can be nested for deeper structure.
Question 36Operators and task construction
What distinguishes a Sensor task from a regular operator task?
- It bypasses the scheduler
- It waits until a condition is met before succeeding Correct answer.
- It cannot be retried
- It always runs asynchronously in a separate process
Explanation
Sensors poll or defer until a condition is satisfied, then succeed; if the condition is not met before timeout they fail. They are still scheduled and subject to retries like other tasks. Deferrable sensors can free a worker slot while waiting.
Question 37Operators and task construction
A sensor has poke_interval=30 and timeout=300. Approximately what happens if the condition is never met?
- It fails after about 300 seconds of polling Correct answer.
- It fails after 30 seconds
- It polls forever until manually cleared
- It succeeds after 10 polls
Explanation
timeout sets the maximum seconds the sensor waits before raising a timeout failure, while poke_interval sets the delay between checks. With these values the sensor checks roughly every 30 seconds and gives up near 300 seconds. It does not poll indefinitely unless timeout is unset.
Question 38Operators and task construction
Which mechanism lets a task pass a small value to a downstream task at runtime?
- Pool
- Connection
- Variable
- XCom Correct answer.
Explanation
XComs store small values keyed by task and run so downstream tasks can pull them. They are intended for metadata, not large datasets, because values are serialized into Airflow's metadata database. Connections and Variables are global configuration rather than per-run data passing.
Question 39Operators and task construction
How can a downstream task receive an XCom pushed by an upstream task using the TaskFlow API?
- Call xcom_push inside the downstream function
- Declare the upstream task's return value as a function parameter Correct answer.
- Store the value in a Variable first
- Set provide_context=True on the downstream task
Explanation
With TaskFlow, returning a value from one task and accepting it as a parameter in another creates an implicit dependency and passes the value as an XCom. Airflow wires the dependency automatically from the argument. Manual xcom_pull is unnecessary in this style.
Question 40Operators and task construction
What does the >> operator do between two task objects?
- Merges the two tasks into one
- Creates a TaskGroup containing both tasks
- Copies the right task's configuration to the left
- Sets the left task as upstream of the right task Correct answer.
Explanation
The bitshift operator declares dependency direction: left >> right means the left task must run before the right. It is shorthand for set_downstream or set_upstream. Chaining several tasks with >> builds a linear pipeline.
Question 41Operators and task construction
A task list is defined as [t1, t2] >> t3. What dependency results?
- t3 must complete before t1 and t2 run
- t1 runs before t2, and both before t3
- t3 runs in parallel with t1 and t2
- Both t1 and t2 must complete before t3 runs Correct answer.
Explanation
A list on the left of >> applies the dependency to each element, so t1 and t2 both become upstream of t3. They are not ordered relative to each other. This is the standard fan-in pattern.
Question 42Operators and task construction
Which argument on an operator controls how many times the task is retried after failure?
- retries Correct answer.
- execution_timeout
- max_active_tis_per_dag
- retry_delay
Explanation
retries sets the number of automatic retry attempts after a task fails. retry_delay controls the wait between attempts, and execution_timeout caps how long one attempt may run. max_active_tis_per_dag limits concurrency rather than retries.
Question 43Operators and task construction
Which setting makes a task raise a failure if a single attempt runs longer than 10 minutes?
- retries=10
- dagrun_timeout=timedelta(minutes=10)
- sla=timedelta(minutes=10)
- execution_timeout=timedelta(minutes=10) Correct answer.
Explanation
execution_timeout is a per-attempt limit; exceeding it fails that task instance, which may then be retried. dagrun_timeout applies to the whole DAG run. sla only records a missed service level and does not fail the task by itself.
Question 44Operators and task construction
What is the purpose of the teardown task relationship in Airflow?
- It cancels all other running DAGs
- It deletes the DAG file from the scheduler
- It removes old logs from the metadata database
- It runs cleanup after its paired setup task and its downstream tasks finish Correct answer.
Explanation
A task marked as teardown via as_teardown runs after the setup task and everything downstream of it, even if those tasks fail. This supports resource cleanup patterns. Setup and teardown pairing replaced older patterns for guaranteed cleanup.
Question 45Operators and task construction
Which approach best avoids duplicating operator code when many similar tasks differ only by a parameter value?
- Write one task and mutate its attributes at runtime
- Loop over the values and instantiate the operator inside the loop Correct answer.
- Create a separate DAG file per value
- Use a single task with a for loop over all values
Explanation
Generating tasks in a loop with distinct task_id values is the idiomatic dynamic-task pattern and keeps each unit independently retryable and visible. Mutating a shared instance or doing all work in one task loses per-item observability. Separate DAG files per value multiply maintenance overhead.
Question 46Operators and task construction
Why is passing large DataFrames through XCom considered poor practice?
- XCom can only carry strings
- XCom is deleted at the end of each task
- XCom requires a paid plugin to work
- XCom values are serialized into the metadata database, which is not built for large payloads Correct answer.
Explanation
XComs are stored in Airflow's metadata database, so large payloads bloat the database and slow the scheduler. The recommended pattern is to persist large data externally and pass a reference such as a path or key. Small metadata values remain appropriate for XCom.
Question 47Operators and task construction
Which operator triggers a separate DAG run and can pass a configuration payload to it?
- TriggerDagRunOperator Correct answer.
- SubDagOperator
- DagRunOperator
- ExternalTaskSensor
Explanation
TriggerDagRunOperator starts another DAG and can supply a conf dictionary that the triggered run reads. ExternalTaskSensor instead waits for another DAG's task to reach a state. SubDagOperator embeds a DAG rather than triggering a top-level run.
Question 48Operators and task construction
A task needs the DAG's logical date inside its Python callable. Which approach works with PythonOperator?
- Read os.environ['AIRFLOW_LOGICAL_DATE']
- Call datetime.now() inside the callable
- Pass the date through op_kwargs at parse time
- Accept **context in the callable and read context['logical_date'] Correct answer.
Explanation
When the callable accepts **context, Airflow injects the task context, which includes logical_date and other run metadata. Reading the wall clock gives the actual execution time rather than the scheduled interval. Environment variables are not populated with the logical date by default.
Question 49Operators and task construction
Which statement about default_args on a DAG is accurate?
- They supply fallback operator arguments such as retries to tasks that do not set them Correct answer.
- They apply only to sensors
- They override any argument explicitly set on an operator
- They are evaluated once per task instance at runtime
Explanation
default_args provides baseline values that individual operators inherit unless they specify their own. Explicit operator arguments take precedence over defaults. Defaults are applied at DAG parse time rather than per task instance.
Question 50Operators and task construction
A task must run only when every one of its upstream tasks has failed at least once. Which trigger_rule expresses this?
- one_success
- one_failed
- all_done
- all_failed Correct answer.
Explanation
The all_failed trigger rule permits the task to run only after every upstream task has ended in a failed state; if even one upstream succeeds, the task is skipped. It is the mirror image of all_success and is commonly used for alerting or cleanup branches dedicated to failure handling.