Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node process performance degradation #272

Closed
toniov opened this issue Sep 5, 2018 · 9 comments
Closed

Node process performance degradation #272

toniov opened this issue Sep 5, 2018 · 9 comments
Labels
community question Further information is requested

Comments

@toniov
Copy link

toniov commented Sep 5, 2018

Hi there,

I think the tracer is having a considerable effect in my node processes performance. When there is a low or moderate load it's not appreciable, but during peak time period the CPU usage grows more than double than before (server load average that used to be 0.5 going to around 2, for example).

Didn't have the chance to profile the app, but the behavior I explained above happened only in the two servers I installed the tracer.

My configuration and other details:

const tracer = require('dd-trace').init({ plugins: false });
tracer.use('express');
tracer.use('http');
tracer.use('elasticsearch');
tracer.use('mysql');
Node version: 8.11.3
Express version: 4.16.3
dd-trace version: 0.5.6
elasticsearch version: 15.1.1
mysql version: 2.11.1
@rochdev
Copy link
Member

rochdev commented Sep 5, 2018

How many spans are generated on average for each request, and how many req/sec are you getting?

If you could provide any output from profiling it would definitely be helpful as well.

Also, just to confirm, are these server load average numbers CPU percentage?

@rochdev rochdev added question Further information is requested community labels Sep 5, 2018
@toniov
Copy link
Author

toniov commented Sep 6, 2018

I'm getting around 200 req/sec per instance, spanning 3 Node processes, so around 66 req/sec per process. Also I think around 3 spans are generated on average each request.

By load average I meant the same that top or uptime show: average of the number of processes which are being executed by the CPU or in waiting state. I just mentioned it to give an idea about how it's affecting the system, globally speaking.
Said as CPU percentage, Node processes went from like 30% of CPU utilization to around 70% during peak time period after installing the tracer.

@rochdev
Copy link
Member

rochdev commented Sep 6, 2018

In my own testing, I am unable to reproduce such a big impact for just a couple hundred requests. If you could provide profiling data it would be very helpful.

If the profiling data is sensitive, please PM me in our public Slack or contact support (you can mention me to them so they can forward it to me).

@ibolmo
Copy link

ibolmo commented Sep 13, 2018

I've ran into this as well. Doing some flamegraphs I discovered that the require-in-the-middle causes most functions imported to no longer be optimized by V8:

Here's the flamegraph with dd-agent:

Here's the flamegraph without dd-trace:

@rochdev
Copy link
Member

rochdev commented Sep 13, 2018

Since require-in-the-middle is only executed when require is called (which in most cases only happens when the app starts) I doubt it would make an impact at runtime.

@ibolmo Can you try with dd-trace, but with plugins disabled? I wonder if maybe the graphql plugin is at fault in your case.

@ibolmo
Copy link

ibolmo commented Sep 25, 2018

@rochdev I agree with the assumption but here's another look with empirical data:

with tracer on:

without tracer on:

It's the same uncached request and payload. Same amount of work the graphql js has to process, but my theory is that the require-in-the-middle doesn't permit v8 to properly optimize the call. Thus every cal is dramatically slower.

@rochdev
Copy link
Member

rochdev commented Sep 27, 2018

One way to test this theory would be to completely exclude dd-trace from the equation and try using only require-in-the-middle.

You could do that with the following snippet:

const Hook = require('require-in-the-middle')
const modules = [
  'graphql/execution/execute.js',
  'graphql/language/parser.js',
  'graphql/validation/validate.js'
]

Hook(modules, (exports, name, basedir) => exports)

If you still get the same behavior, then we'll know for sure it's related to require-in-the-middle. Otherwise it means it's most probably something else.

@bengl
Copy link
Collaborator

bengl commented May 13, 2021

There hasn't been any activity on this thread in a few years, so I'm closing it. If the exact same issue is coming up for anyone, please still feel free to comment or reopen.

@bengl bengl closed this as completed May 13, 2021
@rochdev
Copy link
Member

rochdev commented May 13, 2021

It's also very likely related to #1095

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants