How to Use Startup and Shutdown Events in FastAPI
In FastAPI, use the
@app.on_event("startup") decorator to run code when the app starts, and @app.on_event("shutdown") to run code when the app stops. These events help initialize resources like database connections and clean them up properly.Syntax
FastAPI provides two decorators to handle lifecycle events: @app.on_event("startup") and @app.on_event("shutdown"). You define functions decorated with these to run code when the app starts or stops.
- @app.on_event("startup"): Runs once when the app starts.
- @app.on_event("shutdown"): Runs once when the app is shutting down.
These functions can be async or regular functions.
python
from fastapi import FastAPI app = FastAPI() @app.on_event("startup") async def startup_event(): # Code to run on startup pass @app.on_event("shutdown") async def shutdown_event(): # Code to run on shutdown pass
Example
This example shows how to open a database connection on startup and close it on shutdown. It prints messages to the console to demonstrate when each event runs.
python
from fastapi import FastAPI app = FastAPI() @app.on_event("startup") async def startup_event(): print("Starting up: connecting to database...") # Simulate database connection setup app.state.db = "Database connection established" @app.on_event("shutdown") async def shutdown_event(): print("Shutting down: closing database connection...") # Simulate closing database connection app.state.db = None @app.get("/") async def read_root(): return {"message": "Hello World", "db_status": app.state.db}
Output
Starting up: connecting to database...
Shutting down: closing database connection...
Common Pitfalls
Common mistakes when using startup and shutdown events include:
- Not using
asyncfunctions when performing asynchronous operations, which can cause blocking. - Forgetting to properly close resources like database connections, leading to resource leaks.
- Trying to access app state before it is initialized in startup.
- Placing startup/shutdown code inside route handlers instead of event functions.
Always keep startup and shutdown logic separate and ensure cleanup is done to avoid issues.
python
from fastapi import FastAPI app = FastAPI() # Wrong: startup code inside route (runs on every request, not once) @app.get("/wrong") async def wrong_startup(): print("Connecting to DB on every request - inefficient!") return {"message": "This is wrong"} # Right: use startup event @app.on_event("startup") async def startup_event(): print("Connecting to DB once on startup")
Quick Reference
Use these tips to remember how to use startup and shutdown events:
- Startup: Initialize resources like DB connections, caches, or background tasks.
- Shutdown: Clean up resources to avoid leaks or dangling connections.
- Use
app.stateto store shared objects accessible in routes. - Functions can be
asyncor regular functions. - Events run once per app lifecycle, not per request.
Key Takeaways
Use @app.on_event("startup") to run code once when FastAPI starts.
Use @app.on_event("shutdown") to run cleanup code when FastAPI stops.
Keep resource setup and teardown in these event functions, not in routes.
You can store shared resources in app.state for access during requests.
Startup and shutdown functions can be async for non-blocking operations.