Problem
Using the PHP Agent with an application that has long running tasks causes high memory usage.
Solution
To support distributed tracing, the PHP agent needs to keep a significant amount of function call data at runtime so that spans can be sampled as accurately as possible. For web transactions and shorter background transactions, this is generally unnoticeable, both in terms of CPU and memory overhead. However, for longer background transactions, the increased memory overhead may become noticeable, even to the point of resulting in an out of memory condition.
If the affected transaction is one that performs a series of repetitive processes, such as a message queue consumer or a loop with multiple external calls, you may wish to manually instrument each iteration as a separate transaction. By doing this, the memory used will be freed after each transaction.
Starting and stopping transactions manually has the following benefits:
- Allows all PHP agent features to remain enabled.
- Provides more fine-grained data on how the process is operating.
To implement this, first ignore the initial automatic transaction with newrelic_end_transaction()
, then use newrelic_start_transaction()
and newrelic_end_transaction()
to instrument each transaction in turn.
The following code sample shows how to do this. In actual code you would replace the while()
structure with a proper PHP looping statement and insert the function logic in the place of the ellipses.
function example_long_task() { // Ensure PHP agent is available and // stop recording the current transaction if (extension_loaded('newrelic')) { newrelic_end_transaction(); }
// replace next while statement with actual loop while (<condition>) { if (extension_loaded('newrelic')) { // start recording a new transaction newrelic_start_transaction(ini_get("newrelic.appname")); transaction }
// your function logic starts ... ... // your function logic stops
// end transaction for current loop if (extension_loaded('newrelic')) { newrelic_end_transaction(); } }}