<commit_before>---
title: Easy profiling for Node.js Applications
layout: docs.hbs
---

# Easy profiling for Node.js Applications

There are many third party tools available for profiling Node.js applications
but, in many cases, the easiest option is to use the Node.js built in profiler.
The built in profiler uses the [profiler inside V8][] which samples the stack at
regular intervals during program execution. It records the results of these
samples, along with important optimization events such as jit compiles, as a
series of ticks:

```
code-creation,LazyCompile,0,0x2d5000a337a0,396,"bp native array.js:1153:16",0x289f644df68,~
code-creation,LazyCompile,0,0x2d5000a33940,716,"hasOwnProperty native v8natives.js:198:30",0x289f64438d0,~
code-creation,LazyCompile,0,0x2d5000a33c20,284,"ToName native runtime.js:549:16",0x289f643bb28,~
code-creation,Stub,2,0x2d5000a33d40,182,"DoubleToIStub"
code-creation,Stub,2,0x2d5000a33e00,507,"NumberToStringStub"
```

In the past you need the V8 source code to be able to interpret the ticks.
Luckily, tools have recently been introduced into Node.js 4.4.0 that facilitate
the consumption of this information without separately building V8 from source.
Let's see how the built-in profiler can help provide insight into application
performance.

To illustrate the use of the tick profiler, we will work with a simple Express
application. Our application will have two handlers, one for adding new users to
our system:

```javascript
app.get('/newUser', function (req, res) {
  var username = req.query.username || '';
  var password = <PASSWORD>.query.password || '';

  username = username.replace(/[!@#$%^&*]/g, '');

  if (!username || !password || users.username) {
    return res.sendStatus(400);
  }

  var salt = crypto.randomBytes(128).toString('base64');
  var hash = crypto.pbkdf2Sync(password, salt, 10000, 512);

  users[username] = {
    salt: salt,
    hash: hash
  };

  res.sendStatus(200);
});
```

and another for validating user authentication attempts:

```javascript
app.get('/auth', function (req, res) {
  var username = req.query.username || '';
  var password = req.query.password || '';

  username = username.replace(/[!@#$%^&*]/g, '');

  if (!username || !password || !users[username]) {
    return res.sendStatus(400);
  }

  var hash = crypto.pbkdf2Sync(password, users[username].salt, 10000, 512);

  if (users[username].hash.toString() === hash.toString()) {
    res.sendStatus(200);
  } else {
    res.sendStatus(401);
  }
});
```

*Please note that these are NOT recommended handlers for authenticating users in
your Node.js applications and are used purely for illustration purposes. You
should not be trying to design your own cryptographic authentication mechanisms
in general. It is much better to use existing, proven authentication solutions.*

Now assume that we've deployed our application and users are complaining about
high latency on requests. We can easily run the app with the built in profiler:

```
NODE_ENV=production node --prof app.js
```

and put some load on the server using ab:

```
curl -X GET "http://localhost:8080/newUser?username=matt&password=password"
ab -k -c 20 -n 250 "http://localhost:8080/auth?username=matt&password=password"
```

and get an ab output of:

```
Concurrency Level:      20
Time taken for tests:   46.932 seconds<commit_msg>Add information that ab is ApacheBench (#1037)<commit_after>---
title: Easy profiling for Node.js Applications
layout: docs.hbs
---

# Easy profiling for Node.js Applications

There are many third party tools available for profiling Node.js applications
but, in many cases, the easiest option is to use the Node.js built in profiler.
The built in profiler uses the [profiler inside V8][] which samples the stack at
regular intervals during program execution. It records the results of these
samples, along with important optimization events such as jit compiles, as a
series of ticks:

```
code-creation,LazyCompile,0,0x2d5000a337a0,396,"bp native array.js:1153:16",0x289f644df68,~
code-creation,LazyCompile,0,0x2d5000a33940,716,"hasOwnProperty native v8natives.js:198:30",0x289f64438d0,~
code-creation,LazyCompile,0,0x2d5000a33c20,284,"ToName native runtime.js:549:16",0x289f643bb28,~
code-creation,Stub,2,0x2d5000a33d40,182,"DoubleToIStub"
code-creation,Stub,2,0x2d5000a33e00,507,"NumberToStringStub"
```

In the past you need the V8 source code to be able to interpret the ticks.
Luckily, tools have recently been introduced into Node.js 4.4.0 that facilitate
the consumption of this information without separately building V8 from source.
Let's see how the built-in profiler can help provide insight into application
performance.

To illustrate the use of the tick profiler, we will work with a simple Express
application. Our application will have two handlers, one for adding new users to
our system:

```javascript
app.get('/newUser', function (req, res) {
  var username = req.query.username || '';
  var password = req.query.password || '';

  username = username.replace(/[!@#$%^&*]/g, '');

  if (!username || !password || users.username) {
    return res.sendStatus(400);
  }

  var salt = crypto.randomBytes(128).toString('base64');
  var hash = crypto.pbkdf2Sync(password, salt, 10000, 512);

  users[username] = {
    salt: salt,
    hash: hash
  };

  res.sendStatus(200);
});
```

and another for validating user authentication attempts:

```javascript
app.get('/auth', function (req, res) {
  var username = req.query.username || '';
  var password = req.query.password || '';

  username = username.replace(/[!@#$%^&*]/g, '');

  if (!username || !password || !users[username]) {
    return res.sendStatus(400);
  }

  var hash = crypto.pbkdf2Sync(password, users[username].salt, 10000, 512);

  if (users[username].hash.toString() === hash.toString()) {
    res.sendStatus(200);
  } else {
    res.sendStatus(401);
  }
});
```

*Please note that these are NOT recommended handlers for authenticating users in
your Node.js applications and are used purely for illustration purposes. You
should not be trying to design your own cryptographic authentication mechanisms
in general. It is much better to use existing, proven authentication solutions.*

Now assume that we've deployed our application and users are complaining about
high latency on requests. We can easily run the app with the built in profiler:

```
NODE_ENV=production node --prof app.js
```

and put some load on the server using ab (ApacheBench):

```
curl -X GET "http://localhost:8080/newUser?username=matt&password=password"
ab -k -c 20 -n 250 "http://localhost:8080/auth?username=matt&password=password"
```

and get an ab output of:

```
Concurrency Level:      20
Time taken for tests:   46.932 seconds
{'fraction_non_alphanumeric': 0.11251111769937741, 'fraction_numerical': 0.053957900978357544, 'mean_word_length': 4.796391752577319, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7137969', 'n_tokens_mistral': 2292, 'n_tokens_neox': 1993, 'n_words': 718}