Last modified: Oct 19, 2026

Track Django Errors with Sentry

Production errors are expensive. Users see them first, and you find out too late.

Sentry changes that. It captures errors in real time and shows you the stack trace, the user, and the exact release that broke.

This guide shows you how to track Django errors with Sentry. It covers installation, configuration, manual captures, performance tracing, and clean monitoring habits.

Why Use Sentry with Django

Django is powerful, but production is unpredictable. A single unhandled exception can break a checkout flow.

Sentry gives you real-time alerts and rich context. You see the request URL, headers, and local variables.

It also groups duplicate errors into issues. That keeps your inbox clean and helps you prioritize what matters.

Beyond errors, Sentry adds performance tracing. It shows slow views, database spans, and N+1 query patterns.

Install the Sentry SDK

Start inside your virtual environment. Install the SDK with the Django extra.

pip install --upgrade "sentry-sdk[django]"

The [django] extra is optional but recommended. It pins compatible helper dependencies.

If you have not set up Sentry yet, follow a guide to install sentry-sdk in Python before continuing.

Pin the version in requirements.txt. Reproducible deploys matter for monitoring.

Configure Sentry in settings.py

Call sentry_sdk.init() once, as early as possible. Your settings.py is the natural place.

Never hardcode the DSN. Read it from an environment variable.

# settings.py
import os
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration

SENTRY_DSN = os.environ.get("SENTRY_DSN")

if SENTRY_DSN:
    sentry_sdk.init(
        dsn=SENTRY_DSN,
        integrations=[DjangoIntegration()],
        traces_sample_rate=0.2,
        send_default_pii=False,
        environment=os.environ.get("DJANGO_ENV", "production"),
    )

The DjangoIntegration hooks into Django's request cycle. It captures unhandled exceptions automatically.

Modern SDKs auto-enable Django integration when Django is installed. Passing it explicitly is fine and makes your intent clear.

Set traces_sample_rate to a low value in production. 0.2 traces 20% of requests and controls cost.

Keep send_default_pii as False unless your privacy policy allows user data. This is a safe default.

Capture Errors Automatically

Once configured, Sentry captures unhandled exceptions in views, middleware, templates, and management commands.

Trigger a test error in a view. Then check your Sentry project for a new issue.

# views.py
def broken_view(request):
    return 1 / 0  # ZeroDivisionError captured automatically

The issue appears within seconds. You get a full stack trace and request data.

This automatic capture is the core value. You write no per-view error handling.

Capture Handled Errors Manually

Some errors are caught in try/except blocks. Sentry does not see them automatically.

Use capture_exception() to report a handled exception. You still want visibility even after graceful recovery.

import sentry_sdk

def sync_invoice(request, invoice_id):
    try:
        push_to_accounting(invoice_id)
    except AccountingAPIError as exc:
        sentry_sdk.capture_exception(exc)
        return render(request, "invoices/failed.html", status=502)

For non-exception events, use capture_message(). This is useful for recording important state changes.

sentry_sdk.capture_message(f"Invoice {invoice_id} synced", level="info")

Add context with set_user() and set_tag(). Context turns a bare stack trace into a debuggable issue.

sentry_sdk.set_user({"id": request.user.id, "username": request.user.username})
sentry_sdk.set_tag("tenant", request.tenant.slug)
sentry_sdk.set_tag("payment_provider", "stripe")

Breadcrumbs record the trail of events before an error. Add them to understand the user's path.

sentry_sdk.add_breadcrumb(
    category="checkout",
    message="Coupon applied",
    level="info",
)

If your project uses advanced query filtering, pair Sentry with tools like django-filter in Python to keep views clean and errors focused.

Add Performance Tracing

Errors are only half the story. Slow requests lose users just as fast.

With traces_sample_rate above zero, Sentry records transactions. Each request becomes a trace with spans for database queries, cache calls, and templates.

This is how you find slow endpoints and N+1 queries. Sentry flags repeated, near-identical database spans.

You can also wrap custom hot paths with start_transaction() and start_span().

import sentry_sdk

def generate_report(user):
    with sentry_sdk.start_transaction(op="task", name="generate_report"):
        with sentry_sdk.start_span(op="db", description="aggregate orders"):
            data = aggregate_orders(user)
        with sentry_sdk.start_span(op="pdf", description="render pdf"):
            return render_pdf(data)

Tracing volume counts against your Sentry quota. Tune the sample rate deliberately.

If you also run load tests, you can write Locust tasks in Python and watch failures appear in Sentry during test runs.

Reduce Noise with Filtering

Not every exception deserves an alert. Use before_send to drop or modify events.

Use ignore_errors for exceptions that never need reporting.

from django.http import Http404

def before_send(event, hint):
    exc = hint.get("exc_info")
    if exc and isinstance(exc[1], Http404):
        return None  # drop the event entirely
    return event

sentry_sdk.init(
    dsn=SENTRY_DSN,
    before_send=before_send,
    ignore_errors=[KeyboardInterrupt],
)

Use traces_sampler to skip health checks and other low-value transactions.

def traces_sampler(ctx):
    path = ctx.get("wsgi_environ", {}).get("PATH_INFO", "")
    if path.startswith("/healthz"):
        return 0.0
    return 0.2

sentry_sdk.init(dsn=SENTRY_DSN, traces_sampler=traces_sampler)

Clean filtering keeps your dashboard actionable. Noise hides real problems.

Verify Your Setup

Verification proves the SDK can reach Sentry. It also confirms your DSN is valid.

Call flush() before the process exits. The SDK sends events asynchronously, so fast exits can drop data.

import sentry_sdk

sentry_sdk.capture_message("Sentry Django verification test", level="info")
sentry_sdk.flush(timeout=2)
print("Test message sent. Check your Sentry dashboard.")
Test message sent. Check your Sentry dashboard.

Wait about 30 seconds. The message should appear in your project's Issues tab.

Troubleshoot Common Issues

Most problems fall into three categories. DSN errors, import order, and dependency conflicts.

If nothing reaches Sentry, check the DSN. It must match your project exactly, including the organization and project IDs.

If SDK options do not apply, another package may be initializing Sentry first. Dependencies like django-q-sentry can create a second client and override your settings.

For KeyError: request or middleware conflicts, isolate dependencies one by one. Downgrade packages to find the culprit.

If uWSGI cannot find the package, add an explicit --pythonpath pointing to your environment.

Best Practices for Clean Tracking

Pin the SDK version in your dependency file. Monitoring code should be as stable as your application code.

Set the environment tag to "production", "staging", or "development". Filter issues by environment to avoid confusion.

Set the release tag to your deployed version. This unlocks release health and suspect commits.

Keep send_default_pii off by default. Scrub sensitive fields in before_send if needed.

Start with a low traces_sample_rate and adjust upward only when necessary. Tracing volume affects cost.

Review your Sentry issues weekly. Resolve fixed errors and archive noise. A clean dashboard stays useful.

Conclusion

Tracking Django errors with Sentry is a short setup with long-term value. Install the SDK, configure it in settings.py, and let automatic capture do the heavy lifting.

Use manual captures for handled exceptions. Add tags and breadcrumbs for context. Enable tracing to find slow requests.

Filter noise and verify your setup before deploying. With these steps, you gain real-time visibility into every error and performance bottleneck in your Django application.