Background Tasks¶
What are Background Tasks?¶
Background tasks are operations that run independently from the main request-response cycle of your web application. Instead of making the client wait for all operations to complete, you can offload non-critical work to run in the background, allowing your endpoint to return a response quickly.
Why Use Background Tasks?¶
Performance¶
Running all operations synchronously within a request handler can significantly slow down your API responses. Background tasks allow you to defer time-consuming operations, reducing response times and improving overall application performance.
For example, sending an email confirmation might take 2-3 seconds. Without background tasks, your user would have to wait that entire time before receiving a response. With background tasks, the response is instant.
User Experience¶
Users expect fast, responsive applications. By moving non-essential operations to the background, you can provide immediate feedback to users while still ensuring all necessary work gets done.
Resource Optimization¶
Background tasks help you manage server resources more efficiently by:
- Allowing you to process multiple requests concurrently
- Preventing request timeouts on long-running operations
- Enabling better control over when and how tasks execute
Separation of Concerns¶
Background tasks help maintain clean code architecture by separating the core business logic (that affects the response) from ancillary operations (that can be scheduled asynchronously).
Background Tasks in FastAPI¶
FastAPI provides a built-in BackgroundTasks class that runs tasks after the response is sent to the client.
This is useful for simple use cases, but it has limitations:
- Tasks always run after the response is sent
- No control over task execution timing
- Limited error handling options
- Tasks are cancelled if the server shuts down
Enter fastapi-tasks¶
fastapi-tasks extends FastAPI's background task capabilities by providing:
Precise Timing Control
Choose exactly when your tasks are scheduled:
- Immediately - Start concurrent operations right away
- After Route - Schedule tasks before sending the response (fire-and-forget)
- After Response - Schedule tasks after the client receives the response
Task Shielding
Protect critical tasks from cancellation during server shutdown, ensuring important operations complete even when the server is stopping.
Enhanced Error Handling
Define custom error handlers for graceful failure recovery, logging, and retry logic.
Type Safety
Full type hints and generic support for better IDE integration and fewer runtime errors.
When to Use fastapi-tasks¶
Use fastapi-tasks when you need:
- Fine-grained timing control - Different tasks need to be scheduled at different points in the request lifecycle
- Critical task protection - Some operations must complete even during shutdown (e.g., payment processing)
- Advanced error handling - Custom error recovery logic for different task types
- Complex workflows - Multiple tasks with different timing and error handling requirements
For simple "fire and forget" tasks that always are scheduled after the response, FastAPI's built-in BackgroundTasks may be sufficient.
Common Use Cases¶
Email Notifications¶
Send welcome emails, password reset links, or order confirmations without making users wait.
@app.post("/users")
async def create_user(email: str, tasks: Tasks) -> dict:
user_id = create_user_in_db(email)
# Send email after response is sent
tasks.after_response.schedule(send_welcome_email, email)
return {"user_id": user_id}
Analytics and Logging¶
Track user actions and API usage without impacting response times.
@app.post("/orders")
async def create_order(order_data: dict, tasks: Tasks) -> dict:
order = save_order(order_data)
# Log analytics immediately, concurrently with response
tasks.schedule(track_order_event, order.id, "created")
return {"order_id": order.id}
Data Processing¶
Generate thumbnails, process uploads, or update search indexes asynchronously.
@app.post("/upload")
async def upload_image(file: UploadFile, tasks: Tasks) -> dict:
file_path = save_file(file)
# Start processing immediately
tasks.schedule(generate_thumbnails, file_path)
tasks.schedule(update_search_index, file_path)
return {"status": "uploaded", "path": file_path}
Cache Management¶
Warm caches or invalidate stale data after updates.
@app.put("/products/{product_id}")
async def update_product(product_id: int, data: dict, tasks: Tasks) -> dict:
product = update_product_in_db(product_id, data)
# Clear cache after response is sent
tasks.after_response.schedule(invalidate_product_cache, product_id)
return {"product": product}
Next Steps¶
Now that you understand what background tasks are and why they're useful, learn about the different timing modes
that make fastapi-tasks powerful:
- Timing Modes - Deep dive into immediate, after-route, and after-response execution
- First Steps - Get started with your first background task