From 0c2fd9cacb840a75674c2d9b6664074a1d4e7221 Mon Sep 17 00:00:00 2001 From: LakshmiSravyaVedantham <38032391+LakshmiSravyaVedantham@users.noreply.github.com> Date: Wed, 25 Feb 2026 12:14:21 -0800 Subject: [PATCH 1/2] perf: use load_only() in eager_load_dag_run_for_validation to reduce data fetched MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The get_dag_runs API endpoint was slow on large deployments because eager_load_dag_run_for_validation() used selectinload on task_instances and task_instances_histories without restricting which columns were fetched. This caused SQLAlchemy to load all heavyweight columns (executor_config with pickled data, hostname, rendered fields, etc.) for every task instance across every DAG run in the result page — even though only dag_version_id is needed to traverse the association proxy to DagVersion. Add load_only(TaskInstance.dag_version_id) and load_only(TaskInstanceHistory.dag_version_id) to the selectinload chains so the SELECT for task instances fetches only the identity columns and the FK needed to resolve the dag_version relationship, significantly reducing the volume of data transferred from the database on busy deployments. Fixes #62025 --- .../src/airflow/api_fastapi/common/db/dag_runs.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py b/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py index 4eb586c851b77..2970551183b12 100644 --- a/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py +++ b/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py @@ -18,7 +18,7 @@ from __future__ import annotations from sqlalchemy import func, select -from sqlalchemy.orm import joinedload, selectinload +from sqlalchemy.orm import joinedload, load_only, selectinload from sqlalchemy.orm.interfaces import LoaderOption from airflow.models.dag import DagModel @@ -41,13 +41,23 @@ def eager_load_dag_run_for_validation() -> tuple[LoaderOption, ...]: - """Construct the eager loading options necessary for a DagRunResponse object.""" + """Construct the eager loading options necessary for a DagRunResponse object. + + For the list endpoint (get_dag_runs), loading all task instance columns is + wasteful because we only need the dag_version_id FK to traverse to DagVersion. + Using load_only() on TaskInstance and TaskInstanceHistory restricts the SELECT + to just the identity columns and dag_version_id, avoiding large intermediate + result sets caused by loading heavyweight columns (executor_config, etc.) for + every task instance across every DAG run returned by the query. + """ return ( joinedload(DagRun.dag_model), selectinload(DagRun.task_instances) + .load_only(TaskInstance.dag_version_id) .joinedload(TaskInstance.dag_version) .joinedload(DagVersion.bundle), selectinload(DagRun.task_instances_histories) + .load_only(TaskInstanceHistory.dag_version_id) .joinedload(TaskInstanceHistory.dag_version) .joinedload(DagVersion.bundle), joinedload(DagRun.dag_run_note), From 088df3cb9de81493c2ddfcda5a0b75e359982771 Mon Sep 17 00:00:00 2001 From: pierrejeambrun Date: Fri, 6 Mar 2026 11:40:48 +0100 Subject: [PATCH 2/2] Fix static checks --- airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py b/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py index 2970551183b12..750a4ae61aa68 100644 --- a/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py +++ b/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py @@ -18,7 +18,7 @@ from __future__ import annotations from sqlalchemy import func, select -from sqlalchemy.orm import joinedload, load_only, selectinload +from sqlalchemy.orm import joinedload, selectinload from sqlalchemy.orm.interfaces import LoaderOption from airflow.models.dag import DagModel @@ -41,7 +41,8 @@ def eager_load_dag_run_for_validation() -> tuple[LoaderOption, ...]: - """Construct the eager loading options necessary for a DagRunResponse object. + """ + Construct the eager loading options necessary for a DagRunResponse object. For the list endpoint (get_dag_runs), loading all task instance columns is wasteful because we only need the dag_version_id FK to traverse to DagVersion.