License Type | SaaS & On-Premise |
Agent Mode | Assess & Protect |
Main Product Category | Node.js Agent |
Sub Category | Performance |
Question
Does the Node.js agent affect my application's performance?
Answer
As you might expect, Contrast's analysis does make your app run a little slower. The good news is it's generally not enough for anyone to complain about, and the results are definitely worth it.
Startup Time
When you start your server with Contrast, you'll notice a delay in startup time. This is first caused by the agent attempting to establish a connection with the Contrast application. High latency between the server and the Contrast application, or a Contrast application which is under heavy load, may exacerbate the startup time. Where startup time is critical, this cost can be reduced as follows:
- Run Contrast with
--agent.auto_update.enable false
. This will prevent the agent from checking for updates during its initial communication with the Contrast application. - Run Contrast with
--inventory.analyze_libraries false
. The agent will not collect information about the application's dependencies. - Enable Rewrite Caching (see below)
Rewrite Caching
When the rewrite_caching
option enabled the agent permits the rewritten source code to be cached to disk between runs. This allows for a significant improvement in startup time on subsequent application runs with instrumentation enabled.
Instructions
-
Enable rewrite caching with the
agent.node.rewrite_cache.enable true
configuration option -
Optionally, configure a path for where the rewrite cache will reside with the
agent.node.rewrite_cache.path ./contrast_rewrite_cache
configuration option.
By default, the rewrite cache lives under node_modules/.cache/@contrast/agent
. This is a standard location for dependencies to place their caches and is used by a number of popular node modules.
The agent caches files under a folder derived from the instrumented application’s name. This functionality is provided so that a single cache location can support multiple applications.
Caveats
-
The agent cache is invalidated whenever a new version of the agent is installed. This occurs to ensure that we perform rewriting again with the new version in case any new functionality has been introduced
-
When using npm ci to install dependencies, the node_modules folder is removed. If the cache is being stored in its default location this will cause its removal.
-
Performance improvement is proportional to the amount of user code being rewritten.
-
Performance improvement is only noticed at require time. Caching should not be expected to improve runtime application performance when instrumented.
For most applications, the bulk of the startup time the agents adds is caused by the source code rewrites it performs for instrumentation. This delay scales directly with the amount of source code in the application - dependencies included. Where startup time is critical, this cost can be reduced by running Contrast with --agent.node.enable_rewrite false
. This option is a last resort and should be avoided, as it will drastically reduce the accuracy of our dataflow.
Request Processing Time
It's probably more important to think about how Contrast affects the round-trip time. In typical applications, Contrast may noticeably impact the round-trip time of requests that contain a lot of business logic. Round-trip times for static resources typically don't get measurably worse. In requests where the total round-trip time is dominated by database or Web Service calls, Contrast's effect will be less noticeable.
If better performance is really important to your environment, consider the following options:
- Run Contrast nightly during integration tests
- Run Contrast in an alternate environment (QA system or DEV environment)
- Run Contrast on a single node in a load-balanced environment
Dead-zoning
While it's normal to experience some overhead from our Assess instrumentation, it should not affect performance to the extent that the application is rendered unusable. If such a performance impact is experienced, it may indicate that the agent is monitoring too many calls that it doesn't need to.
For example, the agent may try to observe too many function calls in intentionally slow operations such as the bcrypt
hashing function, and the overhead this causes can cause the application to become very slow to respond.
The agent has built-in measures to avoid these situations as much as possible. To handle them, the agent employs something we call dead-zoning. Dead-zoning disables instrumentation during operations which are too expensive to follow in detail, or which the agent does not need to watch because it provides no benefit.
For example, if we detect that our instrumentation in a library such as bcrypt-js
is responsible for this kind of performance degradation, we will add it to our list of dead-zones.
If you suspect something like this is causing performance issues in your application, you can add a dead-zone for a library with the --agent.node.unsafe.deadzones
option, which accepts a comma-separated list of the modules you wish to dead-zone.
If use of this setting this resolves a performance issue, please reach our to our Support team, especially if the module is a public one available in npm. We can use this information to update our internal dead-zoning policy and improve the way we detect modules which should be dead-zoned automatically.
More Information
For additional detail on how to make any of the configuration changes documented above, please visit Node.js Agent Configuration.