Run tasks in the background
Learn to defer task runs to task workers running in a separate process.
Introduction
Prefect tasks are atomic pieces of work that you might want to cache or retry. Tasks have .submit()
and .map()
methods to simplify concurrent execution of a task in a given workflow.
If you need your task results available to the calling context, you probably want to use Prefect’s task runners via .submit()
or .map()
instead.
Sometimes your parent workflow doesn’t need to resolve a task’s result, it just needs the task to produce some side effect or save a result. In this case, the caller doesn’t need to waste time blocking on the task’s completion - instead, it can “background” that task run somewhere else.
Background tasks are built for this use case. They allow you to defer a task’s execution to a task worker running in a separate process.
Motivating example
Background tasks are useful for dispatching heavy and/or blocking work from your application or workflow to task workers on static infrastructure that you can scale or manage independently.
For example, imagine a web application that needs to trigger an agentic while
loop for each request, which we encapsulate as a @task
-decorated function named run_agent_loop
. The task will likely run longer than an acceptable request-response cycle. You can delay()
the expensive task from your endpoint to any task workers subscribed to run_agent_loop
’s runs.
Define a background task
Define a task by adding the @task
decorator to a Python function (like any other Prefect task)
All task configuration options (e.g. log_prints
, retries
, result_storage
) are supported.
Background task methods
- Use the
.delay()
method to background a run of this task - Use the
.serve()
method orserve()
function to start a task worker and execute any waiting task runs
The .serve()
method starts a task worker subscribed to that specific task’s runs.
.delay()
has the same signature as the @task
decorated function.
Subscribe to many background tasks at once by providing the serve()
utility more than one task:
.map()
accepts Iterable[P.args]
, Iterable[P.kwargs]
or unmapped
inputs as well as the deferred: bool
argument to control whether the tasks are run in the background (instead of the current context’s task runner)
Task workers
Task workers are push-based consumers that subscribe to some set of tasks’ runs. They can subscribe to many tasks, and be safely scaled horizontally (e.g. replicas: 4
).
They generally do not need to be interacted with by Prefect users. Instead, they are started and stopped implicitly when you call .serve()
or serve()
.
Tour of the Prefect background task examples repository
The prefect-background-task-examples repository contains reference implementations of applications leveraging background tasks.
Examples are generally Docker Compose setups that can be run locally with docker compose up
. However, as shown above, you can decouple the task submission and execution however you like.
Step 0: Clone the repository
Step 1: Setup python environment
This example uses uv, which is generally recommended for python dependency management.
Step 2: Connect to Prefect Cloud or a self-hosted Prefect server
Use either Prefect Cloud or a self-hosted Prefect server for these examples.
You must have PREFECT_API_URL
set to a Prefect server or Prefect Cloud API URL.
If using Prefect Cloud, make sure your PREFECT_API_URL
and PREFECT_API_KEY
are set.
Otherwise, start a Prefect server by running one of the following commands:
Step 3: Run the minimal local example
In minimal-local-setup
you’ll find a minimal fastapi
application using background tasks.
There’s a test
script that starts an ephemeral web server and task worker, then sends a demo request and cleans up.
If you’re comfortable, permit and run the script.
Otherwise feel free to run the commands at your own pace in separate terminals.
If you’re already running a Prefect server, kill it for the following steps.
For example, to kill the prefect-server
container started in Step 2, run:
Step 4: Run the minimal docker compose example
In minimal-docker-compose
you’ll find a minimal fastapi
application defined in main.py
with a /POST /job
endpoint that calls process_job.delay(**job_request)
.
Start the Docker Compose stack in detached mode:
Navigate to http://localhost:8000/docs and try out the /POST /job
endpoint.
Watch the logs:
Step 5: Explore the rest of the examples
Check out the rest of the examples in the repository, like fastapi-user-signups
and chaos-duck
.
Next steps
- Learn about Results to enable task caching and idempotency.
- Explore a complete example of a FastAPI application that backgrounds tasks
Was this page helpful?