Managed Apache Airflow hosting

Data and streamingOn-prem or your region

Workflow orchestration from the Apache Software Foundation for data teams that write their pipelines in Python, run next to your databases in Switzerland, the EU or your own datacentre. Pilae runs it on your own servers, or in Zurich, Switzerland, and eleven other Pilae Cloud regions.

Talk to us about Apache Airflow

Licence
Apache-2.0
Runs on
Your own hardware, or any of 10+ Pilae regions — six of them in Switzerland and the EU
Upgrades
Pinned, tested against your configuration, applied in your window
Upstream
airflow.apache.org

Running Apache Airflow in production: what it takes

  1. Build one image for five components

    The upstream Apache Airflow image at a pinned release, with your providers installed against its constraints file and apache-airflow pinned in the same command. The same image runs the API server, the scheduler, the DAG processor, the triggerer and the Celery workers, from one configuration, on PostgreSQL and Redis.

  2. Read DAGs from Git

    The GitDagBundle follows a branch of your repository through a read-only deploy key, and every run keeps the commit it started on until it ends. Triggers cannot load from a bundle, so they ship in the image with the plugins, and a change to them is an image release.

  3. Map directory roles to Airflow roles

    The FAB auth manager signs people in with OpenID Connect to Keycloak or Entra ID, and a short security manager class maps their directory roles to Viewer, User, Op or Admin at every login. The API server answers only on your private network.

  4. Back up the database and the Fernet key together

    The metadata database goes offsite daily, encrypted, to your chosen country, and the Fernet key is escrowed beside it. Once a month we restore both into a scratch environment and test a stored connection, which proves the key matches. airflow db clean prunes old run records on a retention you set.

  5. Upgrade on a copy first

    Each upgrade runs airflow db migrate after a snapshot. Providers are released separately from Airflow and are pinned and upgraded the same way. The Pilae Agent tests the upgrade and parses your DAGs on a copy, waits for your approval, applies it in your window and records it in the console.

What Apache Airflow is, and who runs it

Self-hosted Apache Airflow for scheduled data pipelines

Apache Airflow is a workflow orchestrator from the Apache Software Foundation. Pipelines are written in Python as DAGs: the tasks, the order they run in, and when. Airflow starts them on a timetable, when an upstream asset is updated or when a message arrives on a queue, retries failed tasks as often as each allows, and keeps the history of every run. Providers connect it to databases, object stores, cloud services and most tools a data team already uses.

It suits teams that write Python and need hundreds of batch jobs to run in order, every night, with someone told when one fails. Events processed as they arrive belong in Kafka and Flink, and data flows built in a visual editor fit NiFi better. Airflow often runs the batch work around them, such as refreshing the tables Superset reads. We run it on your own hardware or in the Pilae Cloud region beside the databases its tasks read, one of 10+, six of them in Switzerland and the EU.

Apache Airflow in production: five components and a Fernet key

We run Airflow as five processes on one database. The API server serves the UI and the REST API, and tasks report their state to it through the Task SDK instead of writing to the metadata database. The scheduler decides what runs, the DAG processor parses DAGs from the Git bundle, the triggerer holds deferred tasks while they wait, and Celery workers run the tasks. The metadata database is PostgreSQL, task logs go to a bucket on Garage, and sign-on goes through Keycloak. All of it answers only on your private network. Where a task has to run inside one of your sites, the Edge executor places a worker there that needs only HTTPS to the API server.

The Fernet key encrypts every connection password and variable in the database, so it is escrowed with the backups, which go offsite daily, encrypted, to your chosen country. Our monitoring reads the health endpoint every 60 seconds and alerts an engineer when the scheduler, the DAG processor or the triggerer stops sending heartbeats. The Pilae Agent runs each upgrade and its database migration on a copy first, and applies it in your window once you approve.

Apache Airflow licence and editions

Airflow has no paid edition, so there is no seat count to track and no licence to hold in your name. We operate the Apache release on infrastructure you choose, on the published plans. Talk to us about the DAGs you want to bring across from Astro, Amazon MWAA or Google’s Managed Service for Apache Airflow, formerly Cloud Composer.

Apache Airflow is Apache-2.0, and so are the providers the project publishes to connect it to databases, object stores and cloud services. There is no enterprise edition and no paid build: the scheduler, every executor, the REST API and sign-on through the FAB auth manager are all in the Apache releases we deploy. Astronomer sells Astro, its own commercial platform built on Airflow, under a separate contract with Astronomer, and AWS and Google sell managed Airflow inside their clouds. You do not need any of them for anything on this page. Apache Airflow, Airflow and the Airflow logo are trademarks or registered trademarks of the Apache Software Foundation, which does not endorse this service.

Apache Airflow system requirements

Before anything is deployed, this is what has to exist. We size it with you in the first session, and we say so when your own hardware is already enough.

CPU and memory
4 vCPU · 8 GB, plus workersOur starting point for the API server, scheduler, DAG processor and triggerer on one machine. Workers are sized to the tasks they run: a task that loads a file into memory needs more than one that calls an API and waits.
Metadata database
PostgreSQLHolds DAG runs, task state, serialised DAGs and the encrypted connections and variables. Upstream also supports MySQL. SQLite is for its tests only and MariaDB is not tested, so we use neither.
Executor and queue
CeleryExecutor · RedisCelery workers take tasks from Redis and record results in the database, as upstream recommends. Where you already run Kubernetes, the KubernetesExecutor starts a pod per task instead.
Keys
Fernet key · JWT secretThe Fernet key encrypts connection passwords and variables in the database, and a different key cannot decrypt them, so it is escrowed with the backups. The JWT secret signs the short-lived tokens tasks use to report back, and must be the same on the scheduler and the API server.
DAG repository
Git · read-only deploy keyThe DAG processor and the workers fetch DAGs through the git provider's GitDagBundle, over SSH or HTTPS. Each run records the commit it started on.
Task logs
S3-compatible bucketRemote logging writes the log of every task attempt to a bucket, through an Airflow connection pointed at its endpoint. Without it, logs stay on the worker that ran the task and go when that worker does.

Migrating from Astronomer Astro to Apache Airflow

An Astro project is already an Airflow repository: dags, plugins, include and tests folders, with Python packages in requirements.txt and system packages in packages.txt. The DAG code comes across as it is. The Dockerfile changes: it starts from Astronomer's Astro Runtime image, which we replace with the Apache Airflow image at the same Airflow version, after comparing what each image installs so that nothing a DAG imports leaves with the base image. What stays behind is what Astro keeps outside the repository. Connections, variables and environment variables set in the Astro UI or its Environment Manager are re-created on the new deployment. Astro alerts live in the Astro UI rather than in DAG code, so they become failure callbacks, Deadline Alerts and checks in our monitoring. Run history and task logs stay with the old Deployment. If it still runs the previous major version of Airflow, the move to the current one is most of the work.

  1. Inventory DAGs, packages and settings

    Every DAG with its owner, schedule and last successful run, the Airflow and provider versions the old service runs, and every connection, variable, pool and alert. DAGs nobody has run in months are archived rather than moved.

  2. Move to the current major version in the repository

    ruff with its AIR rules flags most of what the current major version removes or moves, such as imports that moved to airflow.sdk, operators now in the standard provider and removed context variables like execution_date. Tasks that query the metadata database directly are rewritten against the REST API, and SLAs become Deadline Alerts. Each fix is a commit your team reviews.

  3. Replace the cloud's implicit credentials

    On a managed service, tasks often reach that cloud through an identity attached to the environment: the execution role on MWAA, the environment's service account on Google's service. Off those platforms, each such call needs a connection with its own credentials, scoped to what the DAG touches. Cloud operators keep working for as long as the services they call stay in use.

  4. Switch DAG by DAG, never in both places

    Each DAG is deployed paused, run once by hand against test targets, then unpaused on the new Airflow and paused on the old service the same day, so no run executes twice. Catchup is off by default in current Airflow, so nothing backfills unless you ask for it.

One repository for the DAGs, one image for everything else

  • dags/GitDagBundle, tracking_ref main
    • erp_to_warehouse.pynightly, updates the warehouse asset
    • ledger_close.pyscheduled on that asset
    • refresh_extracts.pythe tables dashboards read
  • acme_airflow/installed in the image, not the bundle
    • triggers/the triggerer cannot load from a bundle
    • hooks/shared by DAGs and triggers
  • plugins/copied into the image
  • requirements.txtproviders and libraries, pinned
  • Dockerfileapache/airflow at the pinned release, with its constraints
  • deploy/one configuration for every component
    • compose.yamlapi-server, scheduler, dag-processor, triggerer, workers
    • airflow.envexecutor, bundle, remote logging
    • webserver_config.pyOIDC to sso.acme.internal, roles at every login
  • /run/secretsnot in Git
    • fernet_keyescrowed with the database backups
    • jwt_secretsame on scheduler and API server
    • git_deploy_keyread-only
  • s3://acme-airflow-logsGarage, remote task logs
    • dag_id=…/attempt=1.logone file per task attempt
An example repository and deployment for acme. The DAG processor and the workers read dags/ from Git through the GitDagBundle, and each run keeps the commit it started on, so a push in mid-run changes nothing under it. Triggers cannot load from a bundle, so they are built into the image with the plugins and the Python packages, installed against the constraints file of the pinned release. Task logs go to a bucket on Garage and outlive the worker that wrote them. The keys stay out of Git, and the Fernet key is escrowed with the database backups.

What Pilae is responsible for

A pinned version

A version we have run, not whatever latest resolves to that day.

A runbook

What it depends on, how it fails, what to do about it. In your repository.

A restore drill

Backups restored on a schedule. A backup nobody has restored is a file.

A patch window

Security updates in a window you agreed, with a rollback ready.

Someone watching

Every endpoint probed on the minute. An alert reaches a person, not a dashboard nobody opens.

Where it runs
zur1, fra1, fal1, gra1, ams1, hel1, lon1, ash1, hil1, sin1, tok1, syd1, on-premZurich, Frankfurt, Falkenstein, Gravelines, Amsterdam, Helsinki, London, Ashburn, Hillsboro, Singapore, Tokyo, Sydney, Your own hardware
Who holds the credentials
You do. Ours are separate, named, logged and revocable with one command. We ask before anything changes outside an agreed window.
If you leave
The machine, the data, the compose files and the runbook are already yours. Nothing stops when our access does.

What running Apache Airflow costs

On Starter, Apache Airflow runs in Pilae Cloud for CHF 449EUR 479USD 559 a month, hosting and onboarding included. On Business, it is one of up to three apps for CHF 1,590EUR 1,690USD 1,990 a month, on your own servers or in Pilae Cloud. Enterprise is quoted. The plans set what each includes; these are the inputs that move the price around them.

Instance size
The CPU, memory and, where a model runs, the GPUs the app needs for your users and your data.
High availability
One machine with tested restores, or a replicated setup that keeps serving when a node fails.
Storage and backups
How much data it holds, how long backups are kept, and point-in-time recovery for its database.
Plan and support
Starter, Business or Enterprise: support hours, response times in the contract and how often we review the service with you.
Region
Your own hardware, where the infrastructure is already yours, or a Pilae Cloud region, where machines are priced per month. On Starter, Pilae chooses the site.
Sign-on and integrations
Single sign-on, directory sync, mail relays and the other systems the app has to reach.

Apache Airflow: common questions

Is Apache Airflow open source?

Yes. Airflow is Apache-2.0 and a top-level project of the Apache Software Foundation, and the providers that connect it to other systems are published by the same project under the same licence. There is no enterprise edition of Airflow itself. Astronomer sells Astro, a commercial platform built on Airflow, which you do not need for anything on this page.

We are still on the previous major version of Airflow. Does that matter?

Yes. The previous major version of Airflow has reached end of life upstream and gets no further fixes, security fixes included. The move to the current one is mostly DAG code: moved imports, removed context variables such as execution_date, SLAs replaced by Deadline Alerts, and tasks that queried the metadata database directly, which current Airflow no longer allows. ruff flags most of it before anything runs, and we fix the rest with your team.

Where do our DAGs, logs and credentials live?

DAGs in your Git repository. Run history and the encrypted connections and variables in PostgreSQL, and task logs in a bucket, on the machines you chose: your own hardware, or dedicated machines in the Pilae region you picked, in ISO 27001-certified datacentres. Backups are encrypted and kept offsite in the country you chose. The data your tasks move stays in the systems they read and write.

Can people sign in with Keycloak or Entra ID?

Yes, through OpenID Connect and the FAB auth manager, with directory roles mapped to Viewer, User, Op and Admin at every login, and access to a single DAG set in the DAG itself. Airflow also has a Keycloak auth manager, but upstream still marks it as alpha and experimental, so we do not run it in production yet.

Is Airflow the right tool for streaming data?

Not on its own. Upstream describes Airflow as a platform for orchestrating batch workflows: a run starts, its tasks do their work, and it ends. In current Airflow a DAG can start when a message arrives on a queue such as Kafka, and the run that follows is still a batch of tasks. Processing every event as it arrives, with state held between events, is work for Kafka and Flink, and Airflow schedules the batch jobs around them.

Also in data and streaming

Back to apps

Bring us your Apache Airflow. We will tell you what it takes.

Thirty minutes on the deployment you already have, or the one you are about to start.