diff --git a/src/node/performance/benchmark_client.js b/src/node/performance/benchmark_client.js
index 5ef5260a96d7e0e740e135372d80af659619a44f..e7c426b2ff5befde3572e2c48fdc41af16730d63 100644
--- a/src/node/performance/benchmark_client.js
+++ b/src/node/performance/benchmark_client.js
@@ -88,7 +88,10 @@ function timeDiffToNanos(time_diff) {
  */
 function BenchmarkClient(server_targets, channels, histogram_params,
     security_params) {
-  var options = {};
+  var options = {
+    "grpc.max_receive_message_length": -1,
+    "grpc.max_send_message_length": -1
+  };
   var creds;
   if (security_params) {
     var ca_path;
@@ -180,6 +183,8 @@ BenchmarkClient.prototype.startClosedLoop = function(
 
   self.last_wall_time = process.hrtime();
 
+  self.last_usage = process.cpuUsage();
+
   var makeCall;
 
   var argument;
@@ -270,6 +275,8 @@ BenchmarkClient.prototype.startPoisson = function(
 
   self.last_wall_time = process.hrtime();
 
+  self.last_usage = process.cpuUsage();
+
   var makeCall;
 
   var argument;
@@ -354,9 +361,11 @@ BenchmarkClient.prototype.startPoisson = function(
  */
 BenchmarkClient.prototype.mark = function(reset) {
   var wall_time_diff = process.hrtime(this.last_wall_time);
+  var usage_diff = process.cpuUsage(this.last_usage);
   var histogram = this.histogram;
   if (reset) {
     this.last_wall_time = process.hrtime();
+    this.last_usage = process.cpuUsage();
     this.histogram = new Histogram(histogram.resolution,
                                    histogram.max_possible);
   }
@@ -371,9 +380,8 @@ BenchmarkClient.prototype.mark = function(reset) {
       count: histogram.getCount()
     },
     time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
-    // Not sure how to measure these values
-    time_user: 0,
-    time_system: 0
+    time_user: usage_diff.user / 1000000,
+    time_system: usage_diff.system / 1000000
   };
 };
 
diff --git a/src/node/performance/benchmark_client_express.js b/src/node/performance/benchmark_client_express.js
index e749956599dc15c30e49c9bf9bb9ce31ef4d6056..157bf1b6dece10b2f8fd679de5b70ffa2d82f047 100644
--- a/src/node/performance/benchmark_client_express.js
+++ b/src/node/performance/benchmark_client_express.js
@@ -95,7 +95,6 @@ function BenchmarkClient(server_targets, channels, histogram_params,
     var host_port;
     host_port = server_targets[i % server_targets.length].split(':');
     var new_options = _.assign({hostname: host_port[0], port: +host_port[1]}, options);
-    new_options.agent = new protocol.Agent(new_options);
     this.client_options[i] = new_options;
   }
 
@@ -137,6 +136,7 @@ BenchmarkClient.prototype.startClosedLoop = function(
   }
 
   self.last_wall_time = process.hrtime();
+  self.last_usage = process.cpuUsage();
 
   var argument = {
     response_size: resp_size,
@@ -207,6 +207,7 @@ BenchmarkClient.prototype.startPoisson = function(
   }
 
   self.last_wall_time = process.hrtime();
+  self.last_usage = process.cpuUsage();
 
   var argument = {
     response_size: resp_size,
@@ -264,9 +265,11 @@ BenchmarkClient.prototype.startPoisson = function(
  */
 BenchmarkClient.prototype.mark = function(reset) {
   var wall_time_diff = process.hrtime(this.last_wall_time);
+  var usage_diff = process.cpuUsage(this.last_usage);
   var histogram = this.histogram;
   if (reset) {
     this.last_wall_time = process.hrtime();
+    this.last_usage = process.cpuUsage();
     this.histogram = new Histogram(histogram.resolution,
                                    histogram.max_possible);
   }
@@ -281,9 +284,8 @@ BenchmarkClient.prototype.mark = function(reset) {
       count: histogram.getCount()
     },
     time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
-    // Not sure how to measure these values
-    time_user: 0,
-    time_system: 0
+    time_user: usage_diff.user / 1000000,
+    time_system: usage_diff.system / 1000000
   };
 };
 
diff --git a/src/node/performance/benchmark_server.js b/src/node/performance/benchmark_server.js
index ea85029d980dd3df3fa5cca6a0c1836fb8fca70b..a4d5ee1c26c29cc749395340c49e350f137bc40d 100644
--- a/src/node/performance/benchmark_server.js
+++ b/src/node/performance/benchmark_server.js
@@ -132,7 +132,12 @@ function BenchmarkServer(host, port, tls, generic, response_size) {
     server_creds = grpc.ServerCredentials.createInsecure();
   }
 
-  var server = new grpc.Server();
+  var options = {
+    "grpc.max_receive_message_length": -1,
+    "grpc.max_send_message_length": -1
+  };
+
+  var server = new grpc.Server(options);
   this.port = server.bind(host + ':' + port, server_creds);
   if (generic) {
     server.addService(genericService, {
@@ -156,6 +161,7 @@ util.inherits(BenchmarkServer, EventEmitter);
 BenchmarkServer.prototype.start = function() {
   this.server.start();
   this.last_wall_time = process.hrtime();
+  this.last_usage = process.cpuUsage();
   this.emit('started');
 };
 
@@ -175,14 +181,15 @@ BenchmarkServer.prototype.getPort = function() {
  */
 BenchmarkServer.prototype.mark = function(reset) {
   var wall_time_diff = process.hrtime(this.last_wall_time);
+  var usage_diff = process.cpuUsage(this.last_usage);
   if (reset) {
     this.last_wall_time = process.hrtime();
+    this.last_usage = process.cpuUsage();
   }
   return {
     time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
-    // Not sure how to measure these values
-    time_user: 0,
-    time_system: 0
+    time_user: usage_diff.user / 1000000,
+    time_system: usage_diff.system / 1000000
   };
 };
 
diff --git a/src/node/performance/benchmark_server_express.js b/src/node/performance/benchmark_server_express.js
index 4b695eb467db12ad3b75ac8380f81c7c7c729e64..fab4f5307c1cd9f93e59555f3984d27db3aab07a 100644
--- a/src/node/performance/benchmark_server_express.js
+++ b/src/node/performance/benchmark_server_express.js
@@ -81,6 +81,7 @@ BenchmarkServer.prototype.start = function() {
   var self = this;
   this.server.listen(this.input_port, this.input_hostname, function() {
     self.last_wall_time = process.hrtime();
+    self.last_usage = process.cpuUsage();
     self.emit('started');
   });
 };
@@ -91,14 +92,15 @@ BenchmarkServer.prototype.getPort = function() {
 
 BenchmarkServer.prototype.mark = function(reset) {
   var wall_time_diff = process.hrtime(this.last_wall_time);
+  var usage_diff = process.cpuUsage(this.last_usage);
   if (reset) {
     this.last_wall_time = process.hrtime();
+    this.last_usage = process.cpuUsage();
   }
   return {
     time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
-    // Not sure how to measure these values
-    time_user: 0,
-    time_system: 0
+    time_user: usage_diff.user / 1000000,
+    time_system: usage_diff.system / 1000000
   };
 };
 
diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py
index 200da5e36db5ea3cd038aa3afe92b3e1d81cd8e2..ce0808829fd559eb9545df2f7ddedaf8adde67f9 100644
--- a/tools/run_tests/performance/scenario_config.py
+++ b/tools/run_tests/performance/scenario_config.py
@@ -513,7 +513,22 @@ class NodeLanguage:
         'node_protobuf_unary_ping_pong_1MB', rpc_type='UNARY',
         client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
         req_size=1024*1024, resp_size=1024*1024,
-        categories=[SCALABLE, SMOKETEST])
+        categories=[SCALABLE])
+
+    sizes = [('1B', 1), ('1KB', 1024), ('10KB', 10 * 1024),
+             ('1MB', 1024 * 1024), ('10MB', 10 * 1024 * 1024),
+             ('100MB', 100 * 1024 * 1024)]
+
+    for size_name, size in sizes:
+      for secure in (True, False):
+        yield _ping_pong_scenario(
+            'node_protobuf_unary_ping_pong_%s_resp_%s' %
+            (size_name, 'secure' if secure else 'insecure'),
+            rpc_type='UNARY',
+            client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
+            req_size=0, resp_size=size,
+            secure=secure,
+            categories=[SCALABLE])
 
     # TODO(murgatroid99): fix bugs with this scenario and re-enable it
     # yield _ping_pong_scenario(
@@ -528,11 +543,10 @@ class NodeLanguage:
     #    client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
     #    unconstrained_client='async')
 
-    # TODO(jtattermusch): make this scenario work
-    #yield _ping_pong_scenario(
-    #    'node_to_cpp_protobuf_async_unary_ping_pong', rpc_type='UNARY',
-    #    client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
-    #    server_language='c++', async_server_threads=1)
+    yield _ping_pong_scenario(
+        'node_to_cpp_protobuf_async_unary_ping_pong', rpc_type='UNARY',
+        client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
+        server_language='c++', async_server_threads=1)
 
     # TODO(jtattermusch): make this scenario work
     #yield _ping_pong_scenario(
@@ -829,6 +843,21 @@ class NodeExpressLanguage:
         unconstrained_client='async',
         categories=[SCALABLE, SMOKETEST])
 
+    sizes = [('1B', 1), ('1KB', 1024), ('10KB', 10 * 1024),
+             ('1MB', 1024 * 1024), ('10MB', 10 * 1024 * 1024),
+             ('100MB', 100 * 1024 * 1024)]
+
+    for size_name, size in sizes:
+      for secure in (True, False):
+        yield _ping_pong_scenario(
+            'node_express_json_unary_ping_pong_%s_resp_%s' %
+            (size_name, 'secure' if secure else 'insecure'),
+            rpc_type='UNARY',
+            client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
+            req_size=0, resp_size=size,
+            secure=secure,
+            categories=[SCALABLE])
+
   def __str__(self):
     return 'node_express'