Skip to main content
Logfire for Django

Django observability with OpenTelemetry

OpenTelemetry-native observability for Django, from the team behind Pydantic. See every request, view, and ORM query as one trace, so N+1 queries and slow endpoints jump out in production, not just in the Debug Toolbar. Free for 10 million spans a month.

Start free As Markdown
Getting started

Instrument Django in settings.py

pip install 'logfire[django,psycopg]'
# settings.py, at the very end, after your other settings

import logfire

logfire.configure()
logfire.instrument_psycopg()   # use the integration that matches DATABASES
logfire.instrument_django()    # keep this last

Put this at the end of settings.py, after the rest of your settings, with instrument_django() last so it wraps the fully-configured app and no request slips through uninstrumented. Swap instrument_psycopg() for the integration that matches your DATABASES engine.

What you get

One request, one trace

A Logfire trace of an HTTP request, broken into nested timed spans including its database queries, filterable with SQL

Every request becomes a trace, the full timeline of one request, built from nested spans, each a timed unit of work, for the view and each ORM query. So an N+1, where the code runs one extra query per row instead of one for all of them, shows up as the same query firing thirty times in one trace, impossible to miss.

How it works

Every request, every query, connected

Catch N+1 queries in production

This is where tracing earns its keep for Django. When your ORM query span shows up thirty times inside a single request, each nearly identical, you have found an N+1, and you have found it against real traffic rather than a synthetic local page. The trace shows the problem and confirms the fix once you add select_related or prefetch_related.

Trace views, tasks, and outbound calls

Add the layers a Django app leans on, one line each: logfire.instrument_django(), logfire.instrument_psycopg(), logfire.instrument_requests(), logfire.instrument_celery(), logfire.instrument_redis(). Call logfire.instrument_celery() in the Celery worker process too, not just the web process, so a task kicked off by a request stays connected to the trace that started it and a slow background job is a single readable story.

Trace your own logic

For business operations, open a span where the work begins with logfire.span("checkout", cart_id=cart.id). It becomes the parent of the auto-instrumented queries and calls it triggers, with attributes you can filter and group on.

Traces, metrics, and logs in one place

Logfire is not just tracing. Send metrics and structured logs alongside your traces, build dashboards, and set alerts, all in the same OpenTelemetry-native project, and query all of it with the same SQL.

Open standard, no lock-in

Logfire is OpenTelemetry underneath. Standard OpenTelemetry tooling works, and you can export the same telemetry to another backend or self-host without touching your app. You instrument once against the open standard.

Query

Query your telemetry with SQL

select
  attributes->>'db.statement' as query,
  count(*) as calls,
  sum(duration) as total_seconds
from records
where attributes->>'db.system' = 'postgresql'
group by query
order by total_seconds desc;

Your traces, metrics, and logs are queryable with real SQL, no proprietary query language to learn. Django developers can investigate production from the first minute.

Comparison

How Logfire compares for Django

Approaches to Django observability compared
Approach Strengths Trade-offs
Django Debug Toolbar Ideal in local development Development only, no production view
Datadog / New Relic Deep APM Proprietary agents, pricing climbs at scale
Sentry Strong error tracking Lighter on tracing and query-level detail
Raw OpenTelemetry + DIY backend Portable and open You run the backend yourself
Pydantic Logfire One-line Django setup, query-level tracing, SQL, hosted Python and OTel-first, so a weaker fit for non-Python stacks; hosted by default, and younger than the incumbents
Decision guide

Is Logfire right for you?

Choose Logfire if

  • You want to see slow requests and ORM queries in production, not just in local dev
  • You want N+1 query patterns to be obvious against real traffic
  • You want views, Celery tasks, and outbound calls connected in one trace
  • You want to query traces, metrics, and logs with PostgreSQL-compatible SQL
  • You want the portability of OpenTelemetry with Python-first ergonomics

Choose a traditional APM if

  • You are already deeply integrated with a specific APM vendor's ecosystem
  • You need a vendor-only integration or compliance capability Logfire does not yet offer
  • You only need local development profiling, where the Django Debug Toolbar is enough
FAQ

Common questions

How do I add OpenTelemetry to a Django application?

Install Pydantic Logfire, call logfire.configure() early in your entry point, then logfire.instrument_django() to trace requests and the integration that matches your database driver, such as logfire.instrument_psycopg() or logfire.instrument_sqlite3(), to trace ORM queries. Logfire is OpenTelemetry-native, so standard OpenTelemetry tooling works as well.

Can observability help me find N+1 queries in Django?

Yes, and it is one of the biggest wins. With database instrumentation enabled, a repeated ORM query shows up as many nearly identical spans inside one request trace. That makes N+1 patterns obvious against real production traffic, and the trace confirms the fix once you add select_related or prefetch_related.

Is this different from the Django Debug Toolbar?

Yes. The Django Debug Toolbar is excellent for local development but runs only there. Logfire gives you the same query-level and timing detail in production, across real requests, background tasks, and external calls, with alerting and history.

Does instrumenting Django slow it down?

Auto-instrumentation is designed for production use. Telemetry is batched and exported asynchronously, and traces can be sampled to control volume, so overhead is small compared to the time saved finding slow queries and failing requests.

See your Django app in production

Get started with 10 million free spans per month. No credit card required.