Status: Draft
Authors: Bolke de Bruin
Created: 2025-10-08
Target Airflow Version: 3.2.0
Related Issues:
This AIP proposes implementing a privacy-first, transparent, and community-governed telemetry system for Apache Airflow using the Apache Software Foundation's Matomo instance as the default collection endpoint. This addresses the complete absence of telemetry data since the removal of Scarf, while learning from past mistakes to ensure community trust.
Currently, Airflow has no telemetry collection capability following the removal of Scarf. While this removal was necessary due to community concerns about privacy and transparency, it has created significant challenges:
The Airflow 2.10.0 release included opt-out telemetry via Scarf, which created significant community backlash due to:
This led to Scarf's removal. However, the need for usage insights remains critical for the project's long-term health and sustainability.
The following minimal data will be collected when telemetry is enabled:
3.2.0) 3.11)docker, kubernetes, systemd, standalone, unknownlinux, darwin, windows)x86_64, arm64)pip, docker, helm, managed_service, unknownapache-airflow-providers-amazon==8.x.y)LocalExecutor, CeleryExecutor, KubernetesExecutor - only executors that are known to 'Official' Airflow otherwise "unspecified")postgres, mysql, sqlite)has_webserver_auth, has_dag_serialization)Note: All counts below have Gaussian noise added (±10% standard deviation) to prevent exact fingerprinting while maintaining statistical usefulness.
1-10, 11-50, 51-100, 101-500, 501-1000, 1000+1-50, 51-250, 251-1000, 1001-5000, 5000+~1000, ~10000)<10, 10-50, 50-100, 100-168 (helps understand CI vs production usage)The following data will explicitly not be collected:
Following community feedback from the Scarf incident, telemetry is opt-in by default. While this typically yields lower participation rates (3-10%), it prioritizes user trust and explicit consent, which is critical for rebuilding community confidence after the previous telemetry issues.
When Airflow is started for the first time (or after upgrade to a version with this AIP):
CLI Installation: A 30-second interactive prompt appears when a TTY is detected:
╔══════════════════════════════════════════════════════════════════╗
║ Apache Airflow Anonymous Telemetry ║
╠══════════════════════════════════════════════════════════════════╣
║ ║
║ Help improve Airflow by sharing anonymous usage data. ║
║ ║
║ We collect: Feature usage, performance metrics, errors ║
║ We DON'T collect: Personal data, file contents, IPs ║
║ ║
║ Privacy protections: ║
║ • Differential privacy (noise added to all counts) ║
║ • Daily rotating session IDs (no long-term tracking) ║
║ • Open source implementation you can inspect ║
║ ║
║ View details: airflow.apache.org/docs/telemetry ║
║ Debug mode: airflow telemetry --debug ║
║ ║
║ Enable telemetry? [y/N] (auto-decline in 10 seconds) ║
╚══════════════════════════════════════════════════════════════════╝
User Options:
Y or y: Enable telemetryN or n or wait 10 seconds: Disable telemetry (default)Non-interactive Mode: If stdin is not a TTY or --non-interactive flag is present, telemetry defaults to disabled (unset)
If no explicit choice has been recorded, the Admin UI displays a dismissible banner:
╭────────────────────────────────────────────────────────────────────╮
│ Help Improve Airflow │
│ │
│ Share anonymous usage data to help us prioritize features. │
│ [Learn More] [Enable Telemetry] [No Thanks] │
╰────────────────────────────────────────────────────────────────────╯
Telemetry Settings Page (Admin > Telemetry Settings):
Telemetry preference is stored in the airflow_settings table:
INSERT INTO airflow_settings (key, value) VALUES
('telemetry.enabled', 'true'),
('telemetry.daily_session_salt', 'random-daily-salt'),
('telemetry.consent_timestamp', '2025-10-08T12:34:56Z'),
('telemetry.last_sent_timestamp', '2025-10-08T13:00:00Z');
Note: No persistent installation UUID is stored to prevent long-term tracking.
Users can override database settings via airflow.cfg:
[telemetry]
# Options: true, false, unset
# unset = defer to database setting (default)
enabled = unset
# Optional: Override collection endpoint
# Default: https://analytics.apache.org/
endpoint = https://analytics.apache.org/
# Collection interval in seconds (default: 86400 = daily)
collection_interval = 86400
# Debug mode - print payloads to stdout instead of sending
debug = false
# Disable telemetry
export AIRFLOW__TELEMETRY__ENABLED=false
# Enable debug mode to see payloads
export AIRFLOW__TELEMETRY__DEBUG=true
AIRFLOW__TELEMETRY__ENABLED[telemetry].enabledFollowing best practices, we provide multiple easy methods to enable or disable telemetry:
export AIRFLOW__TELEMETRY__ENABLED=true or falseenabled = true or false in [telemetry] sectionairflow config set telemetry.enabled true or falseairflow_settings table directlycollection_interval)Apache-Airflow/{version} Telemetry/1.0hash(date + random_salt) - cannot correlate across daysAll numeric counts have Gaussian noise added before transmission:
def add_noise(value: int, sensitivity: float = 0.1) -> int:
"""Add Gaussian noise to protect individual values while maintaining aggregate accuracy.
sensitivity: Standard deviation as percentage of value (default 10%)
"""
noise = random.gauss(0, value * sensitivity)
return max(0, int(value + noise))
# Example: Report "approximately 47" not "exactly 47"
dag_count = add_noise(actual_dag_count, sensitivity=0.1)
Data is aggregated locally before transmission to minimize information leakage:
# Bad: Send every DAG run
for dag_run in dag_runs:
send_telemetry(dag_run)
# Good: Aggregate to daily totals with noise
daily_stats = {
'dag_runs_today': add_noise(len(dag_runs)),
'success_rate': round(success_count / total_count, 2)
}
send_telemetry(daily_stats)
{
"telemetry_version": "1.0",
"timestamp": "2025-10-08T12:00:00Z",
"daily_session_id": "a7b9c2e4",
"airflow_version": "3.2",
"python_version": "3.11",
"deployment_type": "kubernetes",
"install_method": "helm",
"os": "linux",
"architecture": "x86_64",
"database_backend": "postgres",
"executor": "KubernetesExecutor",
"providers": [
{"name": "apache-airflow-providers-amazon", "version": "8.x"},
{"name": "apache-airflow-providers-google", "version": "10.x"}
],
"enabled_features": {
"webserver_auth": true,
"dag_serialization": true
},
"usage_stats": {
"dag_count_tier": "51-100",
"task_count_tier": "251-1000",
"dag_runs_7d": "~2000",
"task_instances_7d": "~25000",
"active_hours_per_week": "100-168"
},
"operator_usage_top10": {
"PythonOperator": "45%",
"BashOperator": "22%",
"S3ToRedshiftOperator": "8%"
}
}
Users can inspect telemetry data before it's sent:
# See exactly what would be sent (without actually sending)
$ airflow telemetry --debug
Telemetry Debug Mode
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Telemetry Status: ENABLED
Endpoint: https://analytics.apache.org/
Next transmission: 2025-10-08 14:23:15 UTC
Payload Preview:
{
"telemetry_version": "1.0",
"airflow_version": "3.2",
...
}
This payload will be sent in 2 hours
Disable with: airflow config set telemetry.enabled false
$ airflow version
Apache Airflow: 3.2.0
Python: 3.11.5
Telemetry: ENABLED (disable: airflow config set telemetry.enabled false)
$ airflow version --no-telemetry
Apache Airflow: 3.2.0
Python: 3.11.5
Running with telemetry disabled
Any changes to the data collected (additions or removals) require:
telemetry_version fieldA public dashboard will be created showing:
Dashboard URL: https://analytics.apache.org/ (to be created)
All telemetry code will be:
airflow/telemetry/ for easy inspectionWe publicly commit to:
Users upgrading from Airflow 3.1.x or earlier to 3.2.0:
New documentation will be added:
/docs/apache-airflow/telemetry.rst/docs/apache-airflow/administration-and-deployment/telemetry.rstDedicated section in every release with telemetry changes
Rationale for rejection: Development prioritization would rely solely on GitHub issues and surveys, which don't represent actual usage patterns. This leads to poor prioritization decisions and wasted effort.
Rationale for rejection: While opt-out would provide better data coverage (20-30% vs 3-10%), it violates the privacy-first principle that's critical for rebuilding trust after the Scarf incident. Given Airflow's history, explicit opt-in is the only approach that respects user autonomy and rebuilds community confidence. We accept lower participation rates as the cost of maintaining trust.
Rationale for rejection: Exact counts could fingerprint individual installations and track them across sessions. Differential privacy with noise prevents this while maintaining statistical usefulness.
Rationale for rejection: A persistent UUID enables long-term tracking of individual installations. Daily rotating session IDs prevent correlation across days while still allowing daily aggregation.
Rationale for rejection: Users can configure this, but default should be ASF-hosted for trust and convenience. Most users won't self-host.
Rationale for rejection: Using ASF infrastructure keeps data under project control and avoids third-party dependencies. Builds more trust with community.
Given typical opt-in participation rates of 3-10%, opt-out would give us much better data coverage. However, after the Scarf incident, explicit user consent is critical for rebuilding trust. We prioritize community trust over data coverage and accept that we'll need creative approaches (surveys, optional extended telemetry programs) to supplement the lower opt-in rates.
Three ways:
airflow telemetry --debug to see the exact payload before transmissionWe legally commit in our telemetry promise to never selling individual-level data. We may share aggregate statistics like "40% of users use feature X" in our reports, but never individual installation data.
No. We use daily rotating session IDs instead of persistent UUIDs. Each day gets a new random session ID that cannot be correlated with previous days.
CI/CD environments should set AIRFLOW__TELEMETRY__ENABLED=false in their environment. The data would also naturally be filtered out on our end due to unusual patterns (hundreds of installations per day from same source).
| Risk | Mitigation |
|---|---|
| Low adoption rate | Accept 5-10% participation as cost of trust-building; supplement with targeted surveys and optional "extended telemetry" programs for willing users; focus on quality of insights over quantity |
| Community backlash | Extensive pre-announcement community engagement; address Scarf learnings explicitly; privacy-first design with differential privacy; explicit opt-in approach prioritizes user trust over data coverage |
| Performance impact | Thorough testing; async transmission; 5s timeout; silent failures; zero impact on Airflow operations |
| Privacy concerns | Differential privacy; noise addition; daily rotating IDs; no persistent tracking; ASF hosting; open source implementation |
| Data not useful | Start minimal; noise level calibrated to maintain statistical significance while protecting privacy |
| ASF infrastructure unavailable | Configuration allows alternative endpoints; silent failure prevents impact |
| False positives in fingerprinting prevention | Noise level calibrated through testing to prevent exact fingerprinting while maintaining aggregate accuracy |
This AIP proposes a privacy-first, transparent, and community-governed telemetry system that rebuilds trust while providing the data Airflow maintainers need to make informed development decisions.
Key improvements over previous attempts:
By learning from the Scarf incident, implementing industry best practices for privacy protection, and prioritizing explicit user consent over data coverage, we can rebuild trust while still gathering valuable (though more limited) insights for project sustainability.
Discussion: https://github.com/apache/airflow/discussions/XXXXX
Vote Thread: TBD after discussion period