home
diamond Go Premium
Data Engineering Path  ·  Airflow
Apache Airflow Logo

XCom — Cross-Communication Between Tasks

🔗 Sharing Data Between Tasks with XCom

XCom (short for "Cross-Communication") is Airflow's mechanism for tasks to exchange small messages and metadata. It is stored in the metadata database and is a core concept for building data-aware pipelines.


How XCom Works

sequenceDiagram
    participant T1 as Task: extract
    participant DB as Metadata DB (XCom Table)
    participant T2 as Task: transform

    T1->>DB: xcom_push(key="file_path", value="s3://bucket/data.csv")
    T1->>DB: xcom_push(key="row_count", value=50000)
    Note over T1,DB: Task 1 pushes metadata

    T2->>DB: xcom_pull(task_ids="extract", key="file_path")
    DB-->>T2: "s3://bucket/data.csv"
    T2->>DB: xcom_pull(task_ids="extract", key="row_count")
    DB-->>T2: 50000
    Note over DB,T2: Task 2 pulls metadata

XCom with Traditional Operators

def extract_data(**kwargs):
    """Extract data and push metadata to XCom."""
    data = fetch_from_api()

    # Push to XCom explicitly
    kwargs['ti'].xcom_push(key='row_count', value=len(data))
    kwargs['ti'].xcom_push(key='file_path', value='s3://bucket/output.csv')

    # Return value is automatically pushed as XCom with key='return_value'
    return {"status": "success", "records": len(data)}


def transform_data(**kwargs):
    """Pull XCom values from upstream task."""
    ti = kwargs['ti']

    row_count = ti.xcom_pull(task_ids='extract', key='row_count')
    file_path = ti.xcom_pull(task_ids='extract', key='file_path')
    extract_result = ti.xcom_pull(task_ids='extract')  # Gets return_value

    print(f"Processing {row_count} rows from {file_path}")

XCom with TaskFlow API (Recommended)

@dag(schedule="@daily", start_date=datetime(2024, 1, 1), catchup=False)
def data_pipeline():

    @task()
    def extract() -> dict:
        """Return value is automatically XCom."""
        return {"file": "s3://bucket/data.csv", "rows": 50000}

    @task()
    def transform(metadata: dict) -> dict:
        """Input parameter automatically pulls from XCom."""
        print(f"Processing {metadata['rows']} rows from {metadata['file']}")
        return {"status": "transformed", "rows": metadata['rows']}

    @task()
    def load(result: dict):
        print(f"Loading {result['rows']} rows")

    # XCom passing is completely automatic
    raw = extract()
    transformed = transform(raw)
    load(transformed)

data_pipeline()
🚨 Caution — XCom Size Limits
XCom values are stored in the metadata database. Do NOT pass large datasets (DataFrames, raw files) through XCom. This will bloat your database and cause performance issues.

✅ Pass through XCom: File paths, row counts, status flags, small JSON configs (< 48 KB)
❌ Don't pass through XCom: DataFrames, CSV contents, raw API responses (> 48 KB)

Inspecting XComs in the Web UI

During DAG execution, you can view the values pushed to XCom for each task run by clicking on the task in the Graph/Grid view and choosing the XComs tab:

Airflow Web UI — XCom Inspector

lock

This content is reserved for Premium Members.

Upgrade to Premium

Entity Details

Create New Item

help

Submit Technical Query

Have a question or run into an issue? Describe it below, upload an optional screenshot, and our engineering team will answer it!

image Attach image (optional)

Submit Feedback

build Free Developer Utility Free Tool
gavel

Privacy & Legal Disclaimer

1. Client-Side Browser Processing

All utility tools on DeepEngineerHub (including Image to PDF, Text Formatters, JSON Converters, and Encryptors) execute 100% locally within your client browser using WebAssembly and JavaScript. No uploaded images, text, or documents are transmitted, collected, or stored on remote servers.

2. Limitation of Liability ("As-Is" Provision)

Tools and services are provided free of charge for convenience and educational purposes "as-is" without warranties of any kind. DeepEngineerHub shall not be held liable for any data loss, formatting inconsistencies, or indirect damages resulting from tool usage.

3. Open Source & Third-Party Software

Certain utilities utilize open-source client libraries (such as jsPDF, Mermaid.js, Pyodide) licensed under MIT, Apache, or BSD open licenses. All intellectual property remains with their respective copyright holders.