Problem
You installed the New Relic Node.js agent, and your Node.js application's memory usage increased.
Solution
There are several possible causes for this memory increase and potential solutions for each.
Node.js provides the Cluster module. This allows for handling requests in parallel by using all processor cores available on a host. However, each cluster worker allocates its own slab buffer for SSL transactions, and keeps its own copy of Node.js agent data. This multiplies the memory overhead by the number of cluster workers used. The is also true if a host runs multiple Node.js applications at the same time.
Solution:
Some cloud service providers use environments that state a higher number of processor cores than can actually be used at any given time. Reducing the number of cluster workers or running without Cluster support may decrease memory usage without impacting performance.
Log messages are logged to disk by default. Due to how message data is handled, message objects may be moved into Old-pointer-space for garbage collection. This means the objects stay in memory for a while, even after all references to them are gone. This leads to a larger amount of memory consumed by a process at any given time. Additional processing time is also used for garbage collection.
Solution:
Depending on your version of the Node.js, the agent may default to the trace
or info
log levels. Decrease logging verbosity to info
or warn
levels to noticeably decrease memory usage and time spent in garbage collection.
Many database drivers use an abstraction called a cursor
. Cursors provide the ability to iterate through the results of queries. For example, the mongodb driver provides cursors when executing find
queries.
Cursors live both as objects in the Node.js runtime and as entities in the MongoDB server. When an application has finished using a cursor
, it should close it to free up resources in both the server and the client application.
In Node.js, it is possible for a cursor to be garbage collected, freeing resources in the application, without closing the cursor
in the server. This may be go unnoticed in the application. However, the New Relic Node.js agent keeps track of open cursors to measure the time spent iterating through results. If your application does not close all the cursors it uses, the agent will continue to track stale cursors and leak memory.
Solution:
Ensure every cursor
created in your application is closed by calling cursor.close()
after the application finishes processing the results of the query.
The Node.js agent records data for each transaction your app handles. Data is generally grouped by transaction name. The memory used by the agent increases with the number of different transactions recorded in each minute-long harvest cycle.
In addition, a larger amount of data is kept during each transaction, but is eventually discarded when the transaction completes. Memory used by the agent increases with the number of concurrent transactions handled by the application.
Solution:
If agent data storage is identified as the cause of a memory usage increase, this can best be addressed by adding additional memory to your host, or by switching to a larger cloud instance.