You installed the New Relic Node.js agent, and your Node.js application's memory usage increased.
There are several possible causes for this memory increase and potential solutions for each.
The first time a Node.js application uses any form of encryption, including SSL and HTTPS, a slab buffer is created. The default size for this buffer is 10 MB.
Applications running in environments where SSL termination on inbound requests occurs in a separate router layer do not normally incur this overhead. Cloud services like Heroku and AWS often operate this way. However, the Node.js agent sends outbound data to New Relic services over HTTPS, and this triggers the allocation of a slab buffer.
In some cases, you can reduce the slab buffer below its 10 MB default.
To set the slab buffer size, use tls.SLAB_BUFFER_SIZE.
When using the New Relic agent, do not set the slab buffer size below 128 KB. The slab buffer allocation should not be reduced for apps that communicate with services or clients using SSL, HTTPS, or any other form of cryptography.
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.
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.
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.
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.
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.