Skip to main content

Running Background Tasks

In many scenarios, you need to perform actions after returning a response to the client so that the user doesn't have to wait for the process to finish. Common examples include sending email notifications, processing uploaded files, or updating a search index.

In this guide, you will build a notification system that writes to a log file after the HTTP response is sent, using the BackgroundTasks class.

Define the Background Function

First, create a standard Python function that performs the work. This function can be a regular def or an async def function. FastAPI will run it appropriately.

def write_notification(email: str, message=""):
with open("log.txt", mode="a") as email_file:
content = f"notification for {email}: {message}\n"
email_file.write(content)

This function takes an email and a message, then appends them to a file named log.txt. Because this involves file I/O, running it inside the main request flow would make the client wait until the file is written.

Add BackgroundTasks to your Path Operation

To schedule a task, you must declare a parameter with the type BackgroundTasks in your path operation function. FastAPI will automatically provide an instance of this class for you.

from fastapi import BackgroundTasks, FastAPI

app = FastAPI()

@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks):
# Task scheduling will go here
return {"message": "Notification sent in the background"}

By including background_tasks: BackgroundTasks in the function signature, FastAPI knows to create a fastapi.background.BackgroundTasks object (which inherits from Starlette's version) and pass it to your function.

Schedule the Task

Use the .add_task() method to register your function and its arguments. The task will be executed immediately after the response is sent to the client.

@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks):
background_tasks.add_task(write_notification, email, message="some notification")
return {"message": "Notification sent in the background"}

The .add_task() method accepts:

  1. The function to be called (write_notification).
  2. Any positional arguments to pass to that function (email).
  3. Any keyword arguments to pass to that function (message="some notification").

When you call this endpoint, the client receives the JSON response {"message": "Notification sent in the background"} immediately. Only then does FastAPI execute write_notification.

Use BackgroundTasks in Dependencies

FastAPI also allows you to inject BackgroundTasks into dependencies. This is useful if you want to trigger background logic based on shared logic, like logging every time a specific query parameter is used.

from fastapi import BackgroundTasks, Depends, FastAPI

app = FastAPI()

def write_log(message: str):
with open("log.txt", mode="a") as log:
log.write(message)

def get_query(background_tasks: BackgroundTasks, q: str | None = None):
if q:
message = f"found query: {q}\n"
background_tasks.add_task(write_log, message)
return q

@app.post("/send-notification/{email}")
async def send_notification(
email: str, background_tasks: BackgroundTasks, q: str = Depends(get_query)
):
message = f"message to {email}\n"
background_tasks.add_task(write_log, message)
return {"message": "Message sent"}

In this example, both the dependency get_query and the path operation send_notification use the same BackgroundTasks object. FastAPI ensures that all tasks added to this object—regardless of where they were added—are executed after the response is delivered.

When to use BackgroundTasks

BackgroundTasks is designed for small, lightweight tasks that share the same resources (like memory and database connections) as your FastAPI application.

  • Use BackgroundTasks for: Simple logging, sending a single email, or small database updates.
  • Use a Task Queue (like Celery or RQ) for: Heavy CPU computation, long-running processes (minutes or hours), or tasks that require complex retry logic and dedicated workers.

Because BackgroundTasks runs in the same process as your application, very heavy tasks could compete for resources with your API's ability to handle new requests.