Apache Airflow best practices for DAG authoring, testing, and production deployment
Scanned 9/9/2026
Install to Claude Code
npx -y skills add baekenough/oh-my-customcode --skill airflow-best-practices --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Airflow Best Practices?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/baekenough-airflow-best-practices-oh-my-customcode)More formats (shields.io, HTML) on the badges page.
---
name: airflow-best-practices
description: Apache Airflow best practices for DAG authoring, testing, and production deployment
scope: core
user-invocable: false
---
# Apache Airflow Best Practices (3.2.0)
## DAG Authoring
### Imports (Airflow 3.x)
- Use `from airflow.sdk import DAG, task, Asset` — the stable public API
- Legacy `from airflow.models import DAG` and `from airflow.decorators import task` are deprecated
### Top-Level Code (CRITICAL)
- Avoid heavy computation at module level (executed on every DAG parse)
- Minimize imports at module level — lazy-load inside `@task` functions
- Never call APIs, query databases, or access Variables at top level
- If Variables needed at top level, enable experimental cache with TTL
### TaskFlow API (Default Pattern)
- Use `@task` decorator for all Python tasks (preferred over classic operators)
- XCom serialization is automatic — return values become XCom
- Use `@task.branch` for branching logic
- Use `@task.sensor` for sensor tasks
### Dynamic Task Mapping
- Use `task.expand()` for runtime-determined task instances
- Combine with `.partial()` for fixed kwargs
- Map over lists, dicts, or XCom outputs from upstream tasks
### Scheduling
- Use cron expressions or timetables for `schedule` parameter
- Set `catchup=False` for most DAGs
- Use data-aware scheduling with `Asset` (replaces `Dataset`) for dependencies
- Configure SLA monitoring
### Task Dependencies
- Use `>>` / `<<` operators for clarity
- Group related tasks with `TaskGroup`
- Avoid deep nesting (max 3 levels)
## Testing
### Local Testing
- Use `dag.test()` in `if __name__ == "__main__":` block for IDE debugging
- Runs all tasks in single serialized process without executor
### Unit Tests
- Test DAG import without errors
- Detect cycles in dependencies
- Mock external connections
- Test task logic independently
### Integration Tests
- Use Airflow test mode
- Validate end-to-end workflows
- Test with sample data
## Production Deployment
### Performance
- Lazy-load heavy libraries inside `@task` functions
- Use connection pooling
- Minimize DAG parse time (target < 30s for all DAGs)
- Enable parallelism appropriately
### Reliability
- Set appropriate `retries` and `retry_delay`
- Use SLA callbacks for monitoring
- Implement proper error handling with `on_failure_callback`
- Log important events
## Migration: 2.x → 3.x
### Deprecated (Remove or Replace)
| Deprecated | Replacement |
|-----------|-------------|
| `from airflow.models import DAG` | `from airflow.sdk import DAG` |
| `from airflow.decorators import task` | `from airflow.sdk import task` |
| `Dataset` | `Asset` |
| `execution_date` in context | `dag_run.logical_date` |
| `conf` in task context | Removed — use Variables or params |
### Architecture Changes
- **AIP-72**: Task Execution Interface — tasks run in isolated subprocesses via Execution API Server
- **AIP-44**: Internal API — components communicate via API, not direct DB access
- **New UI**: React-based web interface (replaces Flask-based UI)
## References
- [Airflow 3.2.0 Best Practices](https://airflow.apache.org/docs/apache-airflow/3.2.0/best-practices.html)
- [Airflow SDK (Task SDK)](https://airflow.apache.org/docs/apache-airflow/3.2.0/authoring-and-scheduling/index.html)
- [Migration Guide 2.x → 3.x](https://airflow.apache.org/docs/apache-airflow/3.2.0/migration-guide.html)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!