Async Tasks & Background Processing
Relevant source files
The following files were used as context for generating this wiki page:
- dev/knowledge/backend/async-tasks.md
- backend/infrahub/services/scheduler.py
- backend/infrahub/workers/infrahub_async.py
- dev/guides/backend/creating-async-tasks.md
- backend/AGENTS.md
- dev/README.md
- specs/archive/ifc-2755-webhook-delivery-operability/plan.md
- specs/infp-409-artifact-regen-triggers/plan.md
Infrahub manages long-running operations, scheduled maintenance, and user-defined logic through an asynchronous task system built on Prefect. This architecture ensures that time-consuming processes, such as schema migrations or artifact generation, do not block the main API event loop and provide visibility into execution state and logs.
Sources: dev/knowledge/backend/async-tasks.md, dev/guides/backend/creating-async-tasks.md:7-14
System Architecture
The async task system decouples task submission from execution. The backend API or internal services submit workflows to a task manager, which interfaces with Prefect to schedule and run the logic on dedicated worker processes.
Component Interaction
The following diagram illustrates the flow of a workflow from submission to completion:
This flow ensures that the user receives an immediate acknowledgment while the actual work happens in the background.
Sources: dev/knowledge/backend/async-tasks.md, backend/AGENTS.md:120-123
Workflow Definitions
Every asynchronous task in Infrahub is represented by a WorkflowDefinition. This metadata defines how the task is categorized, where the code resides, and how it should be scheduled or limited.
Workflow Types
Workflows are categorized into three primary types to determine their visibility and purpose:
| Type | Purpose | User Visibility |
|---|---|---|
CORE | Critical infrastructure operations like branch merges or schema changes. | Visible in Infrahub UI |
USER | User-provided code including transforms, generators, and checks. | Visible in Infrahub UI |
INTERNAL | System maintenance, cleanup, and background synchronization. | Hidden from standard users |
Sources: dev/guides/backend/creating-async-tasks.md:21-27, dev/knowledge/backend/async-tasks.md
Key Metadata Fields
A WorkflowDefinition includes:
name: A unique identifier (lowercase with dashes).moduleandfunction: The Python path to the entry point.cron: Optional schedule for recurring tasks.concurrency_limit: Restricts parallel execution (e.g., to 1 for database-sensitive tasks).
Sources: dev/guides/backend/creating-async-tasks.md:65-98
Implementation Standards
Tasks are implemented as Python functions decorated with @flow.
Flow Requirements
- Context Injection: Every flow must accept an
InfrahubContextparameter, which is injected automatically by the worker. - Logging: Developers must use
prefect.get_run_logger()inside flows and tasks. Standard library loggers do not surface in the Prefect UI. - Composition: The flow function serves as a thin composition root. It resolves singletons (like
get_database()) and delegates business logic to dependency-injected components.
@flow(name="my-workflow", flow_run_name="Process {resource_id}")
async def my_workflow(resource_id: str, branch: str, context: InfrahubContext) -> None:
log = get_run_logger()
log.info(f"Starting workflow for {resource_id} on branch {branch}")
database = await get_database()
async with database.start_session() as db:
# Implementation logic delegated to components
pass
Sources: dev/guides/backend/creating-async-tasks.md:32-58, backend/AGENTS.md:120-123
Tagging System
Tags associate flow runs with specific resources, enabling filtered queries in the UI.
- Creation Tags: Passed during
submit_workflow. These are required for filtering (e.g., filtering tasks by branch). - Runtime Tags: Added via
add_tags()inside the flow for human-readable annotation.
Sources: dev/guides/backend/creating-async-tasks.md:100-113, dev/knowledge/backend/async-tasks.md
Specific Implementations
Webhook Delivery
Webhook deliveries are treated as first-class asynchronous tasks (WEBHOOK_SEND). They use Prefect primitives to handle retries and state tracking without requiring additional database nodes for delivery state.
- Redaction: Request/response headers are redacted before being stored as Prefect artifacts.
- Classification: Failures are classified (e.g.,
CONNECTION,TLS,4xx) to provide clean reasons in the UI rather than raw stack traces.
Sources: specs/archive/ifc-2755-webhook-delivery-operability/plan.md:7-14, 114-123
Artifact Regeneration
Artifact generation is a background process triggered by Git changes or API requests.
- Selective Regeneration: The system uses per-definition predicates to determine if an artifact's query or definition has changed.
- Closure Builders: For complex transforms (Jinja2 or Python), the system walks the dependency tree to ensure all related files are watched.
Sources: specs/infp-468-graphql-error-catalogue/plan.md:9-15, specs/infp-409-artifact-regen-triggers/plan.md:9-17
Summary
Async Tasks and Background Processing provide the foundation for Infrahub's scalability and responsiveness. By utilizing Prefect for task orchestration, the system provides robust logging, scheduling, and error handling for core infrastructure operations, user transforms, and internal maintenance. Developers must adhere to specific logging and composition patterns to ensure tasks remain observable and maintainable.