FastAPI APM Setup: Trace Latency and Errors in Under 10 Minutes

Man presenting and pointing to a whiteboard filled with sticky notes in an orange meeting room
A step-by-step guide to integrating APM in FastAPI for latency tracing and error tracking. Achieve observability in minutes with measurable outcomes.

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:

  1. The api_key is correct and the client is initialized before the FastAPI app
  2. The service_name matches the service in your Lescopr dashboard
  3. 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.