How to Run Non-Blocking Background Tasks in FastAPI with BackgroundTasks
FastAPI’s BackgroundTasks feature lets you register functions that run after a response is sent, enabling non‑blocking operations such as sending emails, logging, or cleaning resources, with simple code examples, parameter details, and insights into its Starlette‑based implementation and limitations.
BackgroundTasks is a concept in Python for executing tasks asynchronously in the background. In the FastAPI framework it is widely used to perform operations such as sending emails, writing logs, or cleaning resources without blocking the main thread. The feature is built on Starlette’s BackgroundTasks implementation and is designed to be lightweight. It can register multiple asynchronous tasks that run automatically after the response is returned, suitable for “non‑real‑time response” scenarios.
Usage
<code>from fastapi import BackgroundTasks, FastAPI
app = FastAPI()
def write_notification(email: str, message=""):
with open("log.txt", mode="w") as email_file:
content = f"notification for {email}: {message}"
email_file.write(content)
@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"}
</code>FastAPI creates a BackgroundTasks object and passes it as a parameter to the endpoint.
The .add_task() method accepts the following arguments:
The task function to run in the background (e.g., write_notification ).
Positional arguments that will be passed to the task function (e.g., email ).
Keyword arguments for the task function (e.g., message="some notification" ).
Multiple tasks can be added at once:
<code>@app.get("/multi-task")
async def multi(background_tasks: BackgroundTasks):
background_tasks.add_task(write_log, "任务1")
background_tasks.add_task(write_log, "任务2")
background_tasks.add_task(send_email, "[email protected]", "任务完成")
return {"message": "三个后台任务已添加"}
</code>Technical Details
The BackgroundTasks class comes directly from Starlette’s starlette.background module. It is re‑exported by FastAPI, so you can import it from fastapi without accidentally using the alternative BackgroundTask class from Starlette.
FastAPI relies on Starlette’s BackgroundTasks mechanism, automatically executing the registered functions when the request’s lifecycle ends. The tasks run in the same process; if an exception occurs before the response is sent, the tasks will not execute. Tasks start only after the response has been fully sent to the client.
Internally, BackgroundTasks is a wrapper around a task queue that adds the registered functions to Starlette’s response.background :
<code>from starlette.background import BackgroundTasks
background = BackgroundTasks()
background.add_task(func, *args)
return Response("ok", background=background)
</code>When FastAPI generates a Response containing a background field, it automatically invokes the background tasks after the response is returned:
<code>await response(background=BackgroundTasks(...))
</code>This behavior ties the execution of background tasks to the response lifecycle rather than to a separate thread, subprocess, or external queue.
Summary
If you need heavy background computation that does not require sharing the same process memory, tools like Celery —combined with a message broker such as RabbitMQ or Redis—are more appropriate, though they require additional configuration.
However, for accessing variables within the same FastAPI application or for lightweight tasks like sending email notifications, using FastAPI’s built‑in BackgroundTasks is a simple and effective solution.
Code Mala Tang
Read source code together, write articles together, and enjoy spicy hot pot together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.