
Built-in Background Tasks: Simple and Effective
Send emails and process data without waiting. Learn how to use FastAPI's native BackgroundTasks system to improve user response times.
Built-in Background Tasks: Simple and Effective
In a professional API, you never make a user wait for a process that they don't need an immediate answer to. If a user signs up, they need an immediate "Welcome" page, but they don't need to wait 5 seconds for your server to connect to an external email provider to send the confirmation email.
In this lesson, we learn about FastAPI's built-in BackgroundTasks system.
1. The Problem: Response Latency
Imagine an endpoint that processes an image and sends an email.
@app.post("/signup")
async def signup(user_data: UserCreate):
save_to_db(user_data) # 10ms
send_welcome_email(user_data.email) # 2000ms (Slow!)
return {"message": "Success"}
Total Wait Time: 2+ seconds. This is a bad user experience.
2. The Solution: BackgroundTasks
BackgroundTasks is a simple class provided by FastAPI. You add a function to it, and FastAPI will run that function after it has already sent the response back to the user.
from fastapi import BackgroundTasks
def send_email_task(email: str):
# Logic to send email
print(f"Email sent to {email}")
@app.post("/signup")
async def signup(user_data: UserCreate, tasks: BackgroundTasks):
save_to_db(user_data)
# Add to the queue
tasks.add_task(send_email_task, user_data.email)
# This return happens IMMEDIATELY
return {"message": "Success! Email is being sent."}
3. How it Works (Under the Hood)
FastAPI runs background tasks using the same Event Loop as your application.
- Pros: Zero setup, no extra servers needed (unlike Celery).
- Cons: Since it uses the same process, if you perform a massive CPU-heavy calculation, it might slow down your main API.
When to use Built-in Tasks:
- Sending Emails.
- Logging data to a secondary database.
- Small clean-up tasks.
4. Injecting Dependencies into Tasks
One major benefit of built-in tasks is that they have access to the same environment as your routes. You can even pass database sessions or shared services into them easily.
Visualizing the Background Flow
sequenceDiagram
participant U as User
participant A as FastAPI App
participant T as Background Worker
U->>A: POST /signup
A-->>U: 200 OK (Instant Feedback)
A->>T: Run send_email_task()
Note right of T: Process continues in background
Summary
- Response Speed: Background tasks are the #1 way to make an API feel "Snappy."
add_task: Use it to register functions to run after the response is sent.- Limits: Use built-in tasks for light I/O work (emails, simple logs).
In the next lesson, we’ll look at Task Queues (Celery and Redis) for heavy industrial workloads.
Exercise: The Log Finisher
You want to log every "Password Change" to a separate security file.
- Create a function
log_security_event(username: str). - Show how you would use
BackgroundTasksto call this function in a/change-passwordroute so the user doesn't wait for the file write.