FastAPI x GenAI

Background Tasks

Last post we taught the API to say "no" cleanly with HTTPException. This one is about saying "yes" fast. Sometimes the real work after a request (sending a welcome email, crunching an uploaded file) is slow, and there is no reason to make the client sit and wait for it. FastAPI lets you fire that work off after the response goes out, with BackgroundTasks.

The idea

Someone publishes a blog. You want to save it and email the author a "you're live" note. Saving is instant, the email is slow. So respond immediately and send the email in the background.

from fastapi import BackgroundTasks, FastAPIfrom pydantic import BaseModelapp = FastAPI()class Blog(BaseModel):    title: str    content: strdef notify_author(title: str):    time.sleep(3) # to simulate emailing    with open("log.txt", mode="a") as log:        log.write(f"Published: {title}\n")@app.post("/blog")async def create_blog(blog: Blog, background_tasks: BackgroundTasks):    background_tasks.add_task(notify_author, blog.title)    return {"message": "Blog published"}

How it works ?

  1. You add one parameter typed as BackgroundTasks. FastAPI sees the type and hands you a ready object, no wiring needed.

  2. notify_author is a plain function. Nothing special, it just does the slow thing.

  3. background_tasks.add_task(notify_author, blog.title) schedules it. The function does not run yet.

  4. You return right away. The client gets the response, then FastAPI runs the task. The "email" never blocks the reply.

Passing arguments

.add_task() takes the function first, then whatever that function needs. Positional and keyword arguments both work, exactly like calling the function normally.

def notify_author(title: str, email: str = ""):    with open("log.txt", mode="a") as log:        log.write(f"Notified {email} about: {title}\n")@app.post("/blog")async def create_blog(blog: Blog, background_tasks: BackgroundTasks):    background_tasks.add_task(notify_author, blog.title, email="author@blog.com")    return {"message": "Blog published"}

Notice you never call notify_author(...) yourself. You hand FastAPI the function and its arguments separately, and it does the calling later. That separation is the whole trick.

Your task function can be def or async def, FastAPI handles both. Reach for plain def when the work is blocking (file writes, most email libraries) so it does not stall the event loop.

When background tasks are not enough

BackgroundTasks runs inside the same process as your app. Great for light stuff: an email, a log line, a small cleanup. But if the job is heavy (resize 200 images, run an LLM over a long document) it will hog the very server that is trying to answer requests.

For that you graduate to a real task queue like Celery, with something like Redis holding the jobs. Different process, sometimes a different machine entirely. For now, if the task is small and quick, BackgroundTasks is all you need.