FastAPI Profiler
fastapi-profiler is a FastAPI Middleware that integrates pyinstrument to provide request profiling and performance analysis for FastAPI applications. It helps developers identify bottlenecks by generating detailed reports (HTML, speedscope, JSON, .prof files). As of version 1.5.0, it supports sampling, error auto-capture, and structured JSON logging. It generally follows a regular release cadence, with several minor releases a year.
Common errors
-
AttributeError: 'str' object has no attribute 'raw_headers'
cause An older version of `fastapi-profiler` (<1.4.1) was incompatible with changes in FastAPI/Starlette's Request object structure, causing this error on certain requests.fixUpgrade `fastapi-profiler` to version 1.4.1 or newer. This issue was addressed in the 1.4.1 release. -
ModuleNotFoundError: No module named 'Jinja2'
cause Attempting to use `is_browser_enable=True` in `FastAPIProfilerMiddleware` without installing the optional `Jinja2` dependency.fixInstall Jinja2 explicitly: `pip install Jinja2` or use the extra: `pip install fastapi-profiler[browser]`. -
Profiler report files are not being generated in the specified directory.
cause The `profiler_dir` is not writable, the `PYINSTRUMENT_PROFILING_ENABLED` environment variable is set to 'false', or `profiler_sample_rate` is too low (or 0.0) for the requests being made.fixEnsure the directory specified by `profiler_dir` has write permissions. Check if `PYINSTRUMENT_PROFILING_ENABLED` is not explicitly set to 'false' in your environment. If using `profiler_sample_rate`, increase its value (e.g., to 1.0 for debugging) to ensure requests are profiled. Make sure requests are actually hitting the FastAPI app with the middleware.
Warnings
- gotcha Running `fastapi-profiler` with `is_print_enable=True` or `is_browser_enable=True` (especially without `profiler_sample_rate`) in high-traffic production environments can introduce significant overhead or generate too many files. The profiler itself consumes CPU and I/O resources.
- gotcha The browser-based HTML report viewer functionality (`is_browser_enable=True`) requires the `Jinja2` package, which is an optional dependency. If not installed, enabling this feature will lead to runtime errors or silent failures.
- gotcha The `log_format='json'` option, introduced in v1.5.0, changes the output format of request logs. If you rely on a specific log parsing setup that expects plain text, switching to JSON might break existing log ingestion pipelines.
Install
-
pip install fastapi-profiler
Imports
- FastAPIProfilerMiddleware
from fastapi_profiler import FastAPIProfilerMiddleware
Quickstart
from fastapi import FastAPI
from fastapi_profiler import FastAPIProfilerMiddleware
import uvicorn
import time
# For local development, you might enable profiling via an env var (e.g., in a .env file)
# PYINSTRUMENT_PROFILING_ENABLED=true
app = FastAPI()
app.add_middleware(
FastAPIProfilerMiddleware,
profiler_dir=".", # Directory to save profile reports (e.g., HTML files)
is_print_enable=True, # Print summary to console
profiler_sample_rate=0.1, # Profile only 10% of requests (v1.5.0+ feature)
always_profile_errors=True, # Always profile 5xx errors regardless of sample rate (v1.5.0+ feature)
# is_browser_enable=True, # Requires `pip install Jinja2` to view reports in browser
# html_file_name="profile_report.html", # Custom HTML report filename
# log_format="json", # v1.5.0+ for structured logging
)
@app.get("/")
async def read_root():
time.sleep(0.05) # Simulate some work
return {"message": "Hello FastAPI Profiler!"}
@app.get("/slow")
async def read_slow():
time.sleep(0.2) # Simulate a slow operation
return {"message": "This was a slow request!"}
# To run this application:
# 1. Save the code as `main.py`
# 2. Run from your terminal: `uvicorn main:app --reload`
# 3. Access in your browser: http://127.0.0.1:8000/ or http://127.0.0.1:8000/slow
# Check your current directory for profile files (.html, .json, .prof) and console output.