Monitor Django With New Relic APM

Instrument a Django app with New Relic: install the Python agent, run Gunicorn and Celery under newrelic-admin, configure app names and environments, track transactions, database queries, and errors, add deploy markers, and control data ingest costs.

Problem statement

You need to see where Django requests spend time, which database queries are slow, and how errors and throughput change after deploys, across web and Celery processes. New Relic's Python agent instruments Django, the ORM, common HTTP clients, Celery, and Redis automatically. Getting useful data in production depends on starting processes correctly, naming apps per environment, and keeping ingest within budget.

New Relic for DjangoPython agentnewrelic.ini or envnewrelic-adminwraps GunicornTransactionsviews, DB, CeleryDashboarderrors, deploysThe agent hooks into Django when it wraps the process start command.
  1. pip install newrelic and set NEW_RELIC_LICENSE_KEY and NEW_RELIC_APP_NAME as environment variables.
  2. Start Gunicorn with newrelic-admin run-program gunicorn config.wsgi ....
  3. Start Celery workers the same way, with their own app name such as shop-worker (prod).
  4. Use separate app names per environment, and record deployments with the release SHA.
  5. Limit ingest: sample transaction traces, drop noisy logs, and disable distributed tracing where unused.

Step-by-step solution

1. Install and configure

pip install newrelic

Configure with environment variables (simplest in containers):

NEW_RELIC_LICENSE_KEY=...
NEW_RELIC_APP_NAME=shop-web (prod)
NEW_RELIC_ENVIRONMENT=production
NEW_RELIC_LOG=stdout
NEW_RELIC_DISTRIBUTED_TRACING_ENABLED=true

Or generate a config file with newrelic-admin generate-config $LICENSE_KEY newrelic.ini and set NEW_RELIC_CONFIG_FILE=/app/newrelic.ini. Environment variables override file settings.

2. Start processes through the agent

newrelic-admin run-program gunicorn config.wsgi --bind 0.0.0.0:8000 --workers 3
NEW_RELIC_APP_NAME="shop-worker (prod)" newrelic-admin run-program celery -A config worker -l info

run-program loads the agent before your code imports Django, so it can instrument everything. With Gunicorn's --preload, the agent still works because it initializes in the master and reconnects in workers.

process and setupStart commandApp nameGunicorn webnewrelic-admin run-programshop-web (prod)Celery workernewrelic-admin run-programshop-worker (prod)Celery beatusually skipn/aManagement commandsbackground_task decoratorshop-jobs (prod)Separate app names keep web and worker metrics apartdjango-deployment.com
Mixing web and worker in one app name makes response time charts misleading.

3. Name transactions and capture context

The agent names web transactions after views automatically. Add custom attributes for useful dimensions:

import newrelic.agent

def checkout(request):
    newrelic.agent.add_custom_attribute("plan", request.user.plan)
    ...

For scripts and management commands, wrap work in a background task:

@newrelic.agent.background_task(name="nightly_report")
def run():
    ...

Ignore expected exceptions (such as Http404) in the error collector settings so error rates reflect real problems.

4. Record deployments

Mark each release so charts show before and after:

curl -X POST "https://api.newrelic.com/graphql" \
  -H "API-Key: $NEW_RELIC_USER_KEY" -H "Content-Type: application/json" \
  -d '{"query":"mutation { changeTrackingCreateDeployment(deployment: {version: \"'"$GIT_SHA"'\", entityGuid: \"'"$ENTITY_GUID"'\"}) { deploymentId } }"}'

Run it from CI after a successful deploy.

5. Control ingest

New Relic bills by data ingested. Keep costs predictable:

  • Leave transaction tracer thresholds at defaults (apdex_f) so only slow requests produce detailed traces.
  • Disable application log forwarding from the agent if logs already go elsewhere (NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED=false).
  • Drop high-cardinality custom attributes such as raw URLs with IDs.
configuration checklistOne app name per process typeand per environmentDeploy markers from CIrelease SHAIgnore expected errorsHttp404, PermissionDeniedLog forwarding off if duplicatedsaves ingestLow-cardinality attributesno raw IDsGood naming and restrained data make dashboards readable and bills stabledjango-deployment.com
Check the data ingest page weekly after launch.

Explanation

The New Relic Python agent patches Django, database drivers, and libraries at import time to time function calls and record transactions. It buffers data in each process and sends it to New Relic's collector in the background. Starting the process through newrelic-admin or calling newrelic.agent.initialize() before Django loads ensures instrumentation is applied. The resulting traces connect slow views to specific queries and external calls.

Edge cases / notes

  • Async views. The agent supports ASGI servers and async views; run Uvicorn through newrelic-admin the same way.
  • Forking. Celery's prefork pool forks after the agent starts; the agent handles reconnection in children.
  • OpenTelemetry. New Relic also accepts OTLP data, if you prefer vendor-neutral instrumentation.

Next steps

FAQ

How do I start Django with the New Relic agent?

Wrap the start command: newrelic-admin run-program gunicorn config.wsgi.

Does New Relic instrument Celery?

Yes. Start the worker through newrelic-admin and give it its own app name.

How do I see the effect of a deploy?

Record deployment markers from CI with the release version.

How can I reduce New Relic costs?

Limit ingest: keep default trace thresholds, avoid duplicate log forwarding, and drop high-cardinality attributes.

Keep going