← Back to blog

Magento 2 New Relic: Finding Slow Requests in Production

Rodrigo Biazzi

When a Magento 2 store is slow in production, guessing is expensive. New Relic APM shows which transactions are slow, which SQL queries and external calls they spend time on, and whether a deploy changed anything. This article covers how to set up New Relic for Magento Open Source and Adobe Commerce 2.4.8, what the built in reporting module does and does not do, and how to read the data to find real problems.

Two separate pieces

People often mix up two things that both carry the New Relic name in Magento:

  • The New Relic PHP agent. A PHP extension plus a daemon installed on each server. This is what collects transaction timings, traces, SQL and external calls. It knows Magento 2 as a framework and names transactions after the controller or route that handled them.
  • The Magento_NewRelicReporting module. A core module that, when enabled, sends extra Magento events such as deploys, admin activity and cron based counts to New Relic, and can set the application name per area. It is a supplement. It does not do the profiling.

You get most of the value from the agent alone. The module is useful but optional.

Installing the agent

Install the agent from the New Relic package repository for your distribution and run the installer, which asks for the license key and writes an ini file for each PHP version it finds. Then check the settings in the generated newrelic.ini:

extension = "newrelic.so"
newrelic.enabled = true
newrelic.license = "YOUR_LICENSE_KEY"
newrelic.appname = "Shop Production"
newrelic.framework = "magento2"
newrelic.transaction_tracer.enabled = true
newrelic.transaction_tracer.detail = 1
newrelic.transaction_tracer.record_sql = "obfuscated"
newrelic.transaction_tracer.slow_sql = true
newrelic.distributed_tracing_enabled = true

Framework detection is usually automatic, but setting it explicitly avoids surprises. record_sql = "obfuscated" replaces literal values in queries with placeholders, so customer emails and addresses do not end up in your APM account. Keep it that way.

Reload PHP-FPM after installing. The agent talks to the local newrelic-daemon, which forwards data to New Relic, so check that the daemon is running.

One app name per environment

Use different app names for production and staging. Mixing them gives averages that describe neither. You can also set the app name per FPM pool with php_value[newrelic.appname] in the pool config, which is handy when admin and storefront run in separate pools.

Enabling the reporting module

The module settings live under Stores, Configuration, General, New Relic Reporting. You need an API key and account details from New Relic. Once enabled, it can:

  • Record deployment markers so you can see each deploy on your charts.
  • Report the application under different names for frontend and admin when you choose to send them as separate apps.
  • Send periodic counts through a cron job, for example of catalog and customer data.

Deployment markers are the part I find most useful. A deploy marker on the response time chart turns "the site got slower last week" into "the site got slower right after Tuesday's release". The module also provides a CLI command for this, bin/magento newrelic:create:deploy-marker, which you can call from the deploy script. Run bin/magento newrelic:create:deploy-marker --help on your version to see the exact arguments it accepts.

Reading the transactions list

In APM, open the transactions view and sort by most time consuming, not by slowest average. A transaction with a slow average but very few calls is a curiosity. The one that takes the most total time is where your server capacity goes.

In Magento the usual top entries are:

  • Category and product view controllers, when they are not cached by Varnish.
  • Customer data section loads, the customer/section/load route, which are never full page cached.
  • Cart and checkout routes, including the REST calls the checkout makes for shipping estimates and totals.
  • GraphQL, if you run a headless storefront.
  • Admin routes and REST API calls from integrations.

If category pages appear high in the list and you run Varnish, the first question is why so many of them reach PHP. That is a cache hit rate problem, not a PHP problem.

Transaction traces

Traces are where the detail is. A trace for a slow request shows a tree of the time spent: which segments of the request took how long, which SQL ran, which HTTP calls went out. With transaction_tracer.detail = 1, the agent records more function level segments. Look for:

  • One query repeated many times. A product collection loaded in a loop, or a repository getById inside a foreach. The trace shows the same SQL with a large call count. This is the classic N+1 problem.
  • External calls. A block that calls a shipping API, a tax service or a recommendation engine during page render. If that service is slow, your page is slow. Those calls should be cached or moved out of the page render.
  • Time in Redis or session. Long waits on session read usually mean session locking with parallel requests from the same browser.
  • Large uninstrumented time. Time that is not SQL, not external, just PHP. That is where a profiler like Blackfire gives more detail.

Custom instrumentation

The agent exposes PHP functions you can call from your own code. Always guard them with extension_loaded('newrelic'), because local and CI environments do not have the extension.

<?php
declare(strict_types=1);

namespace Vendor\ErpSync\Model;

class OrderExporter
{
    public function export(int $orderId): void
    {
        if (extension_loaded('newrelic')) {
            newrelic_add_custom_parameter('order_id', $orderId);
        }

        // export logic
    }
}

Custom parameters show up on traces and in queries, so you can find the slow export for a specific order. Do not add personal data as parameters.

The useful functions for Magento work are newrelic_add_custom_parameter, newrelic_name_transaction to give a meaningful name to something the agent names poorly, newrelic_background_job to mark CLI work as non web, and newrelic_notice_error to report a handled exception you still want to see.

Cron and queue consumers

Cron jobs and message queue consumers run through PHP CLI. Whether the agent reports them depends on whether the extension is loaded for CLI and enabled there. They show up as non web transactions. That view is often more revealing than the web side, because a slow indexer or a consumer that reconnects to the database on every message can load the database server and slow every web request with it.

Long running consumers are a special case. One process can run for hours, and the agent treats the whole run as one transaction unless you split it. If you need per message timings in a custom consumer, mark the transaction boundaries yourself with newrelic_end_transaction and newrelic_start_transaction. The RabbitMQ consumers guide covers how consumers run.

Alerts worth setting

A few alert conditions catch most incidents early:

  • Apdex or response time on the checkout and cart transactions, not just the overall average.
  • Error rate above a threshold.
  • Throughput dropping close to zero, which often means the site is down or a cache layer is serving errors.
  • Database time per request rising, which often comes before a full outage.

What New Relic will not tell you

APM shows production behaviour with real traffic, which is its strength. It samples, though, and traces do not show every function call. For a detailed call graph of one slow request, use a profiler. I cover that in the Blackfire profiling guide. For the database side of the problems you find, see MySQL tuning for Magento.

FAQ

Do I need the Magento New Relic module to use New Relic APM?

No. The PHP agent collects transactions, traces and SQL by itself. The Magento module adds deploy markers, per area app names and some extra reporting.

How do I see Magento deploys in New Relic?

Enable New Relic Reporting in the Magento config and call bin/magento newrelic:create:deploy-marker from your deploy script, or create the marker through the New Relic API directly.

Will New Relic record customer data from SQL queries?

With transaction_tracer.record_sql set to obfuscated, literal values are replaced with placeholders. Keep that setting and do not add personal data as custom parameters.

How much overhead does the New Relic agent add?

It adds some overhead to each request, and detailed tracing adds more. Most stores run it in production without trouble, but measure on your own setup if you are close to capacity.

I am available for freelance Magento and Adobe Commerce work, including performance investigations. If you need help with this, get in touch.

Related articles