FastAPI’s async-first design delivers high performance, but it also introduces complexity in monitoring. Without proper APM (Application Performance Monitoring), latency spikes and unhandled errors in coroutines can go unnoticed until they impact users. This guide walks you through a step-by-step FastAPI APM setup to trace latency, capture errors, and achieve observability in under 10 minutes.
Why APM Matters for FastAPI
FastAPI’s asynchronous nature means traditional synchronous monitoring tools often fall short. Requests may span multiple coroutines, and errors can propagate silently. APM provides the visibility needed to:
- Identify slow endpoints and their root causes (e.g., database queries, external API calls)
- Capture unhandled exceptions with stack traces and context
- Correlate traces across distributed services
- Measure MTTR (Mean Time to Resolution) and uptime with actionable data
Without APM, debugging production issues becomes a guessing game. With it, you gain measurable outcomes like reduced latency, faster incident resolution, and improved reliability.
The Cost of Ignoring APM
Consider a scenario where a FastAPI endpoint occasionally times out. Without APM:
- You lack trace IDs to correlate the issue across services
- You can’t pinpoint whether the bottleneck is in your code, a database, or an external API
- Errors may go unlogged, leading to undetected failures
With APM, you can trace the exact path of a request, identify the slowest component, and resolve issues before they escalate.
Step 1: Choose Your APM Tool
For FastAPI, you need an APM tool that:
- Supports async frameworks (e.g., FastAPI, Starlette)
- Offers distributed tracing for microservices
- Provides error tracking with stack traces and context
- Integrates seamlessly with Python’s async ecosystem
Popular options include:
- Lescopr: Built for modern async stacks, with low-overhead instrumentation and SLA dashboards
- OpenTelemetry: A vendor-agnostic standard for traces and metrics
- Datadog, New Relic, or Dynatrace: Full-featured APM suites with FastAPI support
For this guide, we’ll use Lescopr due to its FastAPI-native integration and focus on developer experience.
Step 2: Install and Configure the APM Client
Install the Lescopr Python SDK
Begin by installing the Lescopr Python client. This library provides automatic instrumentation for FastAPI, including:
- Request tracing
- Error capture
- Performance metrics
Run the following command in your project directory:
pip install lescopr
Initialize the APM Client
Next, initialize the Lescopr client in your FastAPI application. Add the following code to your main.py or wherever you define your FastAPI app:
from fastapi import FastAPI
from lescopr import Lescopr
app = FastAPI()
# Initialize Lescopr APM
lescopr = Lescopr(
service_name="my-fastapi-app",
environment="production",
api_key="YOUR_LESCOPR_API_KEY"
)
# Enable automatic instrumentation for FastAPI
lescopr.instrument_fastapi(app)
Replace YOUR_LESCOPR_API_KEY with your actual Lescopr API key, available in your Lescopr dashboard.
Key Configuration Options
The Lescopr client supports several configuration options to tailor the APM setup to your needs:
service_name: The name of your service (e.g.,my-fastapi-app). This appears in traces and dashboards.environment: The deployment environment (e.g.,production,staging,development).sample_rate: The percentage of requests to trace (default: 100%). Reduce this in high-traffic environments to limit overhead.debug: Enable debug logging for troubleshooting (default:False).
Example with additional options:
lescopr = Lescopr(
service_name="my-fastapi-app",
environment="production",
api_key="YOUR_LESCOPR_API_KEY",
sample_rate=0.5, # Trace 50% of requests
debug=True
)
Step 3: Instrument Your FastAPI Endpoints
Automatic Instrumentation
The lescopr.instrument_fastapi(app) call enables automatic instrumentation for all FastAPI routes. This means:
- Every request is traced with a unique trace ID
- Spans are created for each endpoint, capturing latency and status codes
- Errors are automatically captured with stack traces and context
No additional code is required for basic tracing.
Manual Instrumentation for Custom Logic
For more granular control, you can manually create spans or capture errors in specific parts of your code. Use the lescopr client to:
- Create custom spans for critical sections
- Add tags or metadata to traces
- Capture errors explicitly
Example with manual instrumentation:
from fastapi import FastAPI, HTTPException
from lescopr import Lescopr
import time
app = FastAPI()
lescopr = Lescopr(service_name="my-fastapi-app", api_key="YOUR_LESCOPR_API_KEY")
lescopr.instrument_fastapi(app)
@app.get("/slow-endpoint")
async def slow_endpoint():
# Start a custom span for a slow operation
with lescopr.start_span("slow_operation"):
time.sleep(2) # Simulate a slow operation
# Explicitly capture an error
try:
raise ValueError("Something went wrong")
except ValueError as e:
lescopr.capture_exception(e)
raise HTTPException(status_code=500, detail="Internal error")
In this example:
- A custom span (
slow_operation) is created to track the latency of a specific operation - An error is explicitly captured with
lescopr.capture_exception(e) - The HTTPException is still raised, but the error context is preserved in Lescopr
Step 4: Verify the APM Setup
Check the Lescopr Dashboard
After deploying your FastAPI application with the Lescopr client, navigate to your Lescopr dashboard. You should see:
- A list of traces for recent requests
- Latency metrics for each endpoint
- Error rates and stack traces for unhandled exceptions
If no data appears, verify the following:
- The
api_keyis correct and the client is initialized before the FastAPI app - The
service_namematches the service in your Lescopr dashboard - The environment (e.g.,
production) is configured correctly
Test with Sample Requests
Send a few requests to your FastAPI endpoints to generate traces. For example:
curl http://localhost:8000/slow-endpoint
Refresh the Lescopr dashboard to confirm that traces and errors are being captured.
Step 5: Optimize for Performance and Cost
Reduce Overhead with Sampling
Tracing every request can add overhead, especially in high-traffic environments. Use the sample_rate option to trace a percentage of requests:
lescopr = Lescopr(
service_name="my-fastapi-app",
api_key="YOUR_LESCOPR_API_KEY",
sample_rate=0.1 # Trace 10% of requests
)
This reduces the volume of traces while still providing visibility into performance trends.
Filter Sensitive Data
APM tools may capture sensitive data (e.g., request headers, query parameters). Use the sanitize_fields option to exclude sensitive fields from traces:
lescopr = Lescopr(
service_name="my-fastapi-app",
api_key="YOUR_LESCOPR_API_KEY",
sanitize_fields=["password", "token", "credit_card"]
)
Set Up Alerts for Critical Issues
Configure alerts in Lescopr to notify your team when:
- Latency exceeds a threshold (e.g., 95th percentile > 500ms)
- Error rates spike (e.g., > 1% of requests)
- Uptime drops below a target (e.g., < 99.9%)
Example alert rule for high latency:
- name: "High Latency Alert"
metric: "latency"
threshold: 500 # ms
duration: "5m"
notify: ["team@example.com"]
Step 6: Advanced APM Features
Distributed Tracing
If your FastAPI application interacts with other services (e.g., databases, external APIs), enable distributed tracing to correlate traces across services. Lescopr automatically propagates trace context via HTTP headers.
Example with an external API call:
import httpx
from lescopr import Lescopr
lescopr = Lescopr(service_name="my-fastapi-app", api_key="YOUR_LESCOPR_API_KEY")
@app.get("/external-api")
async def call_external_api():
async with httpx.AsyncClient() as client:
# The trace context is automatically propagated
response = await client.get("https://api.example.com/data")
return response.json()
SLA Dashboards
Use Lescopr’s SLA dashboards to monitor compliance with service-level agreements. Define SLAs for:
- Latency: e.g., 95% of requests < 200ms
- Error rate: e.g., < 0.1% of requests
- Uptime: e.g., > 99.9% availability
Example SLA for latency:
| Metric | Target | Current Value | Status |
|---|---|---|---|
| P95 Latency | < 200ms | 180ms | Passing |
| Error Rate | < 0.1% | 0.05% | Passing |
| Uptime | > 99.9% | 99.95% | Passing |
Error Tracking with Context
Lescopr captures error context to help debug issues faster. This includes:
- Stack traces
- Request and response data (sanitized)
- Environment variables
- Custom tags or metadata
Example of an error with context:
{
"error": {
"type": "ValueError",
"message": "Invalid input",
"stack_trace": "...",
"context": {
"endpoint": "/process-data",
"request_id": "abc123",
"user_id": "user456"
}
}
}
Common Pitfalls and How to Avoid Them
Pitfall 1: Missing Trace Context
Problem: Traces are not correlated across services, making it hard to debug distributed issues.
Solution: Ensure your APM tool propagates trace context via HTTP headers. Lescopr does this automatically for FastAPI.
Pitfall 2: High Overhead from Tracing
Problem: Tracing every request adds latency and resource usage.
Solution: Use sample_rate to reduce the volume of traces. Start with 100% in development, then adjust for production.
Pitfall 3: Sensitive Data in Traces
Problem: APM tools may capture sensitive data (e.g., passwords, tokens).
Solution: Use sanitize_fields to exclude sensitive fields from traces.
Pitfall 4: No Alerts for Critical Issues
Problem: Issues go unnoticed until they impact users.
Solution: Set up alerts for latency, error rates, and uptime in Lescopr.
Measuring Success
After setting up APM, track the following measurable outcomes to gauge success:
- Latency: Reduce P95 latency by identifying and optimizing slow endpoints
- Error rate: Decrease error rates by catching and fixing unhandled exceptions
- MTTR: Improve Mean Time to Resolution by using trace IDs and error context to debug faster
- Uptime: Increase uptime by proactively monitoring and alerting on issues
Example metrics before and after APM:
| Metric | Before APM | After APM | Improvement |
|---|---|---|---|
| P95 Latency | 800ms | 300ms | -62.5% |
| Error Rate | 2% | 0.5% | -75% |
| MTTR | 30 min | 5 min | -83% |
| Uptime | 99% | 99.95% | +0.95% |
Conclusion
Setting up APM for FastAPI is a game-changer for observability. By tracing latency, capturing errors, and monitoring performance, you gain the visibility needed to debug issues faster and improve reliability. This guide walked you through a step-by-step FastAPI APM setup in under 10 minutes, from installation to advanced features like distributed tracing and SLA dashboards.
To go further, Lescopr's documentation covers step-by-step setup for additional use cases, including custom instrumentation, alerting, and compliance monitoring. Start with a free trial to see how Lescopr can help you achieve measurable outcomes like reduced latency, faster incident resolution, and improved uptime.