How to Use Background Tasks in FastAPI – Full Tutorial
FastAPI’s background tasks are a powerful feature that allow you to run functions in the background of request-response cycles. They are useful for operations that need to happen after a response has been returned to the client, such as sending email notifications, processing files, or handling heavy computations.

To use a background task, you can define a function for the task and then include it in your endpoint definition using the BackgroundTasks
parameter. You can then use the add_task
method to add tasks to be run in the background. FastAPI ensures these tasks are executed after the response is sent, improving the overall request-response cycle’s performance.
FastAPI Background Tasks
To understand FastAPI background tasks. Here is the example code that I’ll use in this article:
from fastapi import FastAPI, BackgroundTasks
from datetime import datetime
app = FastAPI()
def log_message(message: str):
with open("log.txt", "a") as log_file:
log_file.write(f"{datetime.now()}: {message}\\n")
@app.post("/send-message/")
async def send_message(message: str, background_tasks: BackgroundTasks):
background_tasks.add_task(log_message, message)
return {"message": "Message received. It will be logged soon."}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
If you have experience with FastAPI, this may be everything you need. Otherwise, read the following sections to understand how each part works.
Step 1 – Setting up Python and Installing FastAPI
To use background tasks in FastAPI, first set up a python virtual environment, activate it, then install FastAPI and an ASGI server like Uvicorn:
python -m venv env
source env/bin/activate # On Windows use `env\\Scripts\\activate`
pip install fastapi uvicorn
Step 2 – Creating a Background Task
To demonstrate background tasks with FastAPI, we will first create a FastAPI project folder named fastapi_bg_tasks
, then open a new file named app.py
inside it:
mkdir fastapi_bg_tasks
cd fastapi_bg_tasks
nano app.py
Inside your app.py
file, import FastAPI
and the BackgroundTasks
class. The example background task we’ll use will need the datetime
module, so we will also import it:
# app.py
from fastapi import FastAPI, BackgroundTasks
from datetime import datetime
Then define the app instance below the imports:
app = FastAPI()
Next, let’s create an example background task. In this demo, we will add a simple logging function:
def log_message(message: str):
with open("log.txt", "a") as log_file:
log_file.write(f"{datetime.now()}: {message}\\n")
This function takes a string message as input and appends it to a file named log.txt
along with the current date and time.
Next, add a POST endpoint below the log_message()
function:
@app.post("/send-message/")
async def send_message(message: str, background_tasks: BackgroundTasks):
background_tasks.add_task(log_message, message)
return {"message": "Message received. It will be logged soon."}
This FastAPI endpoint for POST requests has the following elements:
send_message()
: An asynchronous function that handles POST requests to the/send-message/
endpoint.- message: A query parameter (string) expected in the request. This is the message that will be logged.
- background_tasks: An instance of
BackgroundTasks
that allows adding tasks to be executed in the background.
background_tasks.add_task(log_message, message)
: Schedules thelog_message
function to run in the background with the providedmessage
as an argument.return
: Sends a JSON response indicating that the message was received and will be logged shortly.
Finally, add the following code to run the FastAPI application:
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
At this point the full contents of your FastAPI application will be as follows:
# app.py
from fastapi import FastAPI, BackgroundTasks
from datetime import datetime
app = FastAPI()
def log_message(message: str):
with open("log.txt", "a") as log_file:
log_file.write(f"{datetime.now()}: {message}\\n")
@app.post("/send-message/")
async def send_message(message: str, background_tasks: BackgroundTasks):
background_tasks.add_task(log_message, message)
return {"message": "Message received. It will be logged soon."}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
Step 3 – Running and Testing FastAPI Background Tasks
Run the app.py
application:
uvicorn app:app --reload
You should see the following output:

Use curl
to send a POST request to the /send-message/
endpoint:
curl -X POST "http://127.0.0.1:8000/send-message/?message=Hello"
curl -X POST "http://127.0.0.1:8000/send-message/?message=Hi"
You should receive the following JSON response:

In your uvicorn
server logs, you should see the following logs:
# output
INFO: 127.0.0.1:55296 - "POST /send-message/?message=Hello HTTP/1.1" 200 OK
INFO: 127.0.0.1:55298 - "POST /send-message/?message=Hi HTTP/1.1" 200 OK
You will notice a new log.txt
file inside your project with contents similar to the following:

These log messages are created by the line log_file.write(f"{datetime.now()}: {message}\\n")
inside the log_message()
background task.
Conclusion
Using FastAPI’s BackgroundTasks
, you can easily run background processes without blocking the main thread, allowing your application to handle more requests concurrently. In this tutorial I have demonstrated how to log messages asynchronously, but you can extend this concept to other use cases such as sending emails, processing data, or any other task that can be performed asynchronously.
FAQ: FastAPI Background Tasks
Can Background Tasks in FastAPI handle complex operations?
Yes, Background Tasks in FastAPI can handle complex and time-consuming operations. However, since they run in the same process as your FastAPI application, they can potentially affect the performance if they are very CPU-intensive. For extremely demanding tasks, consider using a dedicated task queue system like Celery with a message broker (e.g., Redis or RabbitMQ) to offload these tasks to worker processes.
How can I ensure Background Tasks are completed in FastAPI?
Background Tasks in FastAPI are designed to run after the response is sent to the client. However, ensuring their completion can be tricky if the server restarts or if there are unhandled exceptions. For critical tasks, consider:
- Implementing retry logic within the background task.
- Using persistent task queues (e.g., Celery) for more robust handling.
- Logging the status and any exceptions within the task for monitoring and debugging purposes.
Here is an example of handling exceptions within a background task:
def log_message(message: str):
try:
with open("log.txt", "a") as log_file:
log_file.write(f"{datetime.now()}: {message}\\n")
except Exception as e:
# Handle or log the exception
print(f"An error occurred: {e}")
Can I cancel or stop a Background Task in FastAPI?
FastAPI’s BackgroundTasks
does not provide built-in functionality to cancel or stop a task once it has been scheduled.
Background Tasks are meant to be lightweight and simple, designed to run quickly after the response is sent. If you need more control over task management, such as cancelling tasks, you may need to use a more advanced task queue system like Celery, which supports task cancellation and state tracking.