Script Valley
FastAPI: Build Production Python APIs
Async Programming and DependenciesLesson 2.5

How to run background tasks in FastAPI without blocking the response

BackgroundTasks, add_task method, background task function, response before task, use cases, limitations vs Celery, task in dependency

Background Tasks in FastAPI

BackgroundTasks lets you schedule work to run after the response is already sent to the client. The response is not delayed. Use it for fire-and-forget operations: sending emails, writing logs, triggering webhooks.

Basic background task

from fastapi import BackgroundTasks, FastAPI

app = FastAPI()

def send_welcome_email(email: str):
    # Runs after response is sent
    print(f"Sending welcome email to {email}")

@app.post("/register/")
def register_user(email: str, background_tasks: BackgroundTasks):
    # ... save user to DB ...
    background_tasks.add_task(send_welcome_email, email)
    return {"message": "Registered"}

FastAPI injects BackgroundTasks automatically. Call add_task with the function and its arguments. The function runs in the same process after the response is sent.

Background tasks in dependencies

def log_request(background_tasks: BackgroundTasks, path: str):
    background_tasks.add_task(write_log, path)

@app.get("/items/", dependencies=[Depends(log_request)])
def list_items():
    return []

BackgroundTasks can be injected into dependencies too, not just route handlers. The tasks accumulate and all run after the route completes.

Limitations

BackgroundTasks is in-process and in-memory. If the server restarts, pending tasks are lost. For durable task queues, retries, or distributed workers, use Celery with Redis or RabbitMQ instead.