Pipeline orchestration is the practice of defining, scheduling, monitoring, and maintaining complex data workflows. This skill covers the three major orchestration frameworks (Airflow, Dagster, Prefect), common DAG design patterns, error handling strategies, and production operational patterns that keep data flowing reliably.
Data pipeline orchestration covering Apache Airflow DAG design patterns, Dagster software-defined assets, Prefect flow composition, retry and backfill strategies, dependency management, dynamic task generation, monitoring and alerting, SLA tracking, cross-system orchestration, and production operation patterns.
How much does it cost?+
Nothing. It ships with Murage, which is open source. Your bots run on the AI plan you already have.
Can I change it?+
Yes. Open it in Settings → Skills to read, edit or duplicate it. Skill Guard scans it again after every edit.
Give your first job to Murage.
Download the app, connect the AI you already pay for, and tell your Chief of Staff what needs doing. Plan on about ten minutes from install to a working team.
from prefect import flow, task, get_run_logger
from prefect.tasks import task_input_hash
from prefect.concurrency import concurrency
from datetime import timedelta
@task(
retries=3,
retry_delay_seconds=[10, 60, 300], # Escalating delays
cache_key_fn=task_input_hash,
cache_expiration=timedelta(hours=1),
timeout_seconds=600,
tags=["extract"],
)
def extract_data(source: str, date: str) -> dict:
logger = get_run_logger()
logger.info(f"Extracting {source} for {date}")
return fetch_source_data(source, date)
@task(retries=2, tags=["transform"])
def transform_data(raw_data: dict, rules: dict) -> dict:
return apply_transformations(raw_data, rules)
@task(tags=["load"])
def load_data(data: dict, target: str):
write_to_target(data, target)
@flow(name="etl-pipeline", log_prints=True)
def etl_pipeline(date: str, sources: list[str]):
"""Main ETL flow with parallel extraction."""
logger = get_run_logger()
# Parallel extraction using .map()
raw_datasets = extract_data.map(source=sources, date=[date] * len(sources))
# Sequential transformation
transformed = []
for raw, source in zip(raw_datasets, sources):
rules = get_transform_rules(source)
result = transform_data(raw.result(), rules)
transformed.append(result)
# Parallel loading
targets = [f"warehouse.{s}" for s in sources]
load_data.map(data=transformed, target=targets)
logger.info(f"ETL complete for {date}, {len(sources)} sources processed")
@flow(name="scheduled-etl")
def scheduled_etl():
"""Scheduled wrapper with error handling."""
from datetime import date
sources = ["orders", "customers", "products", "inventory"]
etl_pipeline(date=date.today().isoformat(), sources=sources)
Retry and Error Handling Patterns
Retry Strategy Decision Matrix
Failure Type
Retry?
Strategy
Max Retries
Backoff
API rate limit
Yes
Exponential + jitter
5
30s, 60s, 120s, 240s
Network timeout
Yes
Linear
3
30s
Auth token expired
Yes (after refresh)
Refresh then retry
2
0s
Data validation
No
Route to DLQ
0
N/A
Schema mismatch
No
Alert and stop
0
N/A
Resource exhaustion
Yes
Exponential
3
60s, 300s, 900s
Upstream not ready
Yes
Fixed interval
10
300s
Airflow Retry Configuration
python
# Task-level retry with exponential backoff
retry_task = PythonOperator(
task_id='api_extract',
python_callable=extract_from_api,
retries=5,
retry_delay=timedelta(minutes=2),
retry_exponential_backoff=True,
max_retry_delay=timedelta(minutes=60),
execution_timeout=timedelta(hours=1),
on_retry_callback=log_retry_attempt,
on_failure_callback=send_failure_alert,
)
# Sensor with timeout (wait for upstream)
from airflow.sensors.external_task import ExternalTaskSensor
wait_for_upstream = ExternalTaskSensor(
task_id='wait_for_raw_data',
external_dag_id='ingestion_dag',
external_task_id='load_complete',
timeout=7200, # Wait up to 2 hours
poke_interval=300, # Check every 5 minutes
mode='reschedule', # Free worker slot while waiting
allowed_states=['success'],
failed_states=['failed', 'skipped'],
)
Backfill Strategies
python
# Airflow: CLI backfill
# airflow dags backfill etl_orders_daily \
# --start-date 2024-01-01 \
# --end-date 2024-01-31 \
# --reset-dagruns
# Dagster: Programmatic backfill
from dagster import build_schedule_context
def trigger_backfill(start_date, end_date):
"""Backfill a date range with concurrency control."""
dates = generate_date_range(start_date, end_date)
# Process in batches to avoid overwhelming systems
batch_size = 5
for batch in chunks(dates, batch_size):
for date in batch:
daily_orders_job.execute_in_process(
partition_key=date,
resources={"warehouse": warehouse_resource}
)
# Wait for batch completion and verify
verify_backfill_batch(batch)
Monitoring and Alerting
Pipeline Health Metrics
yaml
metrics:
dag_level:
- dag_duration_seconds # Total execution time
- dag_success_rate # Success / total runs
- tasks_failed_count # Failed tasks per run
- schedule_delay_seconds # Time from scheduled to actual start
- sla_miss_count # SLA violations
task_level:
- task_duration_seconds # Individual task time
- task_retry_count # Retries before success
- records_processed # Business metric
- data_quality_score # Quality gate result
alerts:
critical:
- condition: "dag_failed AND is_business_critical"
action: pagerduty
- condition: "sla_miss AND severity = 'high'"
action: pagerduty + slack
warning:
- condition: "dag_duration > 2x median"
action: slack
- condition: "task_retry_count > 2"
action: slack
info:
- condition: "backfill_complete"
action: email
Production Operations Checklist
DAG Development:
[ ] Idempotent tasks (re-runnable without side effects)
[ ] Appropriate retry configuration per failure mode
[ ] Timeouts on all tasks (prevent zombie tasks)
[ ] Task-level SLAs for critical paths
[ ] XCom usage minimized (pass references, not data)
[ ] Secrets in secret backend, not in code
Deployment:
[ ] DAG tested locally before deployment
[ ] CI validates DAG parsing (no import errors)
[ ] Database migrations handled before DAG deploys
[ ] Connections and variables configured in target env
[ ] Resource requirements documented (pools, concurrency)
Monitoring:
[ ] SLA miss callbacks configured
[ ] Failure callbacks with actionable alerts
[ ] Duration anomaly detection
[ ] Dependency health checks (upstream sources)
[ ] Worker/scheduler health monitoring
[ ] Log retention and search capability
Operations:
[ ] Backfill runbook documented
[ ] On-call procedures for common failures
[ ] DAG versioning strategy (avoid breaking changes)
[ ] Pool and concurrency limits set
[ ] Cleanup of old DAG runs and logs
When to Use
Use this skill when:
Designing or implementing orchestration engineer solutions
Reviewing or improving existing orchestration engineer approaches
Making architectural or implementation decisions about orchestration engineer
Learning orchestration engineer patterns and best practices
The question is about a fundamentally different technology domain
A more specific sibling skill covers the exact topic needed
The user needs a complete hands-on tutorial rather than expert guidance
Output Format
markdown
# Orchestration Engineer Analysis
## Context Assessment
[Situation summary and constraints]
## Recommended Approach
[Primary recommendation with rationale]
## Implementation Steps
1. [Step with specific details]
2. [Step with specific details]
3. [Step with specific details]
## Trade-offs and Considerations
- [Key trade-off 1]
- [Key trade-off 2]
## Next Steps
- [Immediate action item]
- [Follow-up action item]
Example
Input: "Help me implement orchestration engineer for a medium-scale production application"
Output: A structured analysis covering current state assessment, recommended orchestration engineer approach with specific patterns, implementation roadmap with milestones, and risk mitigation strategies tailored to the application scale and constraints.
Edge Cases
Legacy system integration: When orchestration engineer must coexist with legacy approaches, provide a gradual migration path rather than a complete rewrite
Scale mismatch: When the solution complexity exceeds the project scale, recommend a simpler approach and note when to revisit
Team skill gaps: When the team lacks experience with the recommended approach, include learning resources and simpler alternatives
Conflicting requirements: When constraints conflict (e.g., performance vs. maintainability), explicitly state the trade-off and recommend based on stated priorities