Install the Airflow Triggerer component (a separate process from the scheduler and worker); without it, deferrable operators fall back to blocking execution
Write a custom Trigger class inheriting from BaseTrigger, implementing async def run() which yields TriggerEvent when the awaited condition is met; register it in the provider's triggers module
In the operator's execute() method, call self.defer(trigger=MyTrigger(...), method_name='execute_complete') to suspend the task and release the worker slot; the task state becomes 'deferred' in the UI
Implement execute_complete(self, context, event) on the operator to resume processing once the trigger fires; raise AirflowException on failure events
Set worker_concurrency on the Triggerer in your deployment config; a single Triggerer process can handle thousands of concurrent deferred tasks limited only by async I/O capacity, unlike workers which consume one slot per running task
Known gotchas
Deferrable operators require the Triggerer service to be running; if the Triggerer crashes, all deferred tasks remain stuck in 'deferred' state until the Triggerer restarts and re-registers the triggers
The trigger code must be fully async (no blocking I/O or time.sleep calls); synchronous blocking inside BaseTrigger.run() will stall all triggers sharing that event loop
Not all built-in operators have deferrable variants; check the provider changelog for the *Async suffix operators (e.g., EmrServerlessStartJobRunOperator has a deferrable mode) before writing a custom trigger
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp