Deferred side effects
Record an event or write a notification after returning a response.
FastAPI · Class
BackgroundTasks collects callable work and runs it after FastAPI sends the response. FastAPI injects it into path operations or dependencies, and add_task() accepts a synchronous or asynchronous function with its arguments.
BackgroundTasks is injected into a path operation or dependency and collects callable work for execution after the HTTP response has been sent. Register work with add_task(), which accepts a regular or asynchronous function plus the arguments it needs; FastAPI runs the task for you.
BackgroundTasks(tasks=None)
add_task(func, *args, **kwargs)| Name | Type | Description |
|---|---|---|
tasks | list[starlette.background.BackgroundTask] | None | Optional initial collection of background tasks. |
BackgroundTasks is a task collection; add_task() returns None.
from fastapi import BackgroundTasks, FastAPI
app = FastAPI()
def write_notification(email: str, message: str = ""):
with open("log.txt", "a") as file:
file.write(f"{email}: {message}\n")
@app.post("/send/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks):
background_tasks.add_task(write_notification, email, message="queued")
return {"message": "Notification sent"}The endpoint registers a regular function with positional and keyword arguments; FastAPI runs it after sending the response.
Record an event or write a notification after returning a response.
Send an email or perform another request-independent operation without delaying the client response.
Register tasks from shared dependency logic.
Declare a parameter annotated as BackgroundTasks in a path operation or dependency. FastAPI creates and injects the object, and add_task() registers work that runs after the response is sent.
Follow-up: Can dependencies use it too? Yes: the type can be declared at multiple dependency levels, including sub-dependencies, and FastAPI coordinates the collected tasks.
Call add_task(func, *args, **kwargs). The first argument is the callable, followed by positional and keyword arguments that FastAPI passes when it runs the task.
Follow-up: How would you pass a named option? Supply it as a keyword, such as add_task(write_notification, email, message="queued").
The task runs after the response is sent, so the client does not wait for that work before receiving the response. The callable can be either a normal def or an async def function.
Follow-up: When might this be insufficient? For heavier or distributed processing, use a separate task queue rather than relying on in-process background execution.
BackgroundTaskadd_taskFastAPI dependency injectionpath operation function