Performance testing your API
For any web application, as the traffic increases, it is always necessary to constantly track how the application is performing. Meaning, how much time does it take to serve a request?, how many requests is it able to serve in a specific time frame?, how many concurrent requests can the application process? In short how much load will be able to handle in worst case scenario. Yes, I mean — is the application scalable?
Please note that, this post does not cover performance testing in depth. Its a vast topic and this is just an attempt to explain how quickly we can write a simple performance tests for your NodeJs api or any http api for that matter.
Enough of the theory, lets dive in the details. We will cover following things as part of this post:
- Create a simple NodeJs server with 2 rest API
- Write performance test using loadtest
1. Create a simple NodeJs server with 2 rest API
The idea is to create a couple of rest API.
One is quick enough and returns response without any processing and the other performs certain processing and in turn takes some time to process the request. We will be using express for creating a node server as follows:
var express = require('express');
var app = express();// first api which just responds to the request without any processing
app.get('/ping', (req, res) => {
res.send('pong');
});
// second api which waits for 50 milli seconds before responding
app.get('/heavy-ping', (req, res) => {
setTimeout(() => {
console.info("eating time for demo");
res.send('heavy pong');
}, 50)
});
app.listen(8080);
console.log("Server started on 8080");
You can access both these api from your browser/postman as follows:
http://localhost:8080/ping - quick enoughhttp://localhost:8080/heavy-ping - should take at least 50 milli seconds to process
2. Write performance test using loadtest
For writing the performance test, we will be using 3 npm modules.
- mocha is one of the most widely used framework for testing javascript applications.
- should is a very intuitive assertions library.
- loadtest is the module used for gathering the performance metrics
Below is the test code:
var loadtest = require('loadtest');
var should = require('should');describe("Performance Test", function() {
var noRequestPerHour = 100000;
var avgRequestTime = 1000;
it("performance testing /heaving-ping", function(done) {
this.timeout(1000 * 60); var options = {
"url": 'http://localhost:8080/heavy-ping',
"maxSeconds": 30,
"concurrency": 25,
"statusCallback": statusCallback
}; var gLatency; function statusCallback(latency, result, error) {
gLatency = latency;
} var operation = loadtest.loadTest(options, function(error) {
if (error) {
console.error('Got an error: %s', error);
} else if (operation.running == false) {
console.info("\n==============================\n");
console.info("Requests per hour: " + noRequestPerHour)
console.info("Avg request time(Millis): " + avgRequestTime)
console.info("\n==============================\n")
console.info("Total Requests :", gLatency.totalRequests);
console.info("Total Failures :", gLatency.totalErrors);
console.info("Requests/Second :", gLatency.rps);
console.info("Requests/Hour :", (gLatency.rps * 3600));
console.info("Avg Request Time:",gLatency.meanLatencyMs);
console.info("Min Request Time:",gLatency.minLatencyMs);
console.info("Max Request Time:",gLatency.maxLatencyMs);
console.info("Percentiles :", gLatency.percentiles)
console.info("\n===============================\n") gLatency.totalErrors.should.equal(0);
(gLatency.rps * 3600).should.be.greaterThan(noRequestPerHour);
(gLatency.meanLatencyMs).should.be.below(avgRequestTime); done();
}
});
});
});
Here you create an option object which contains the url to hit, maxSeconds the test should be run, concurrent requests to be made and a callback function to capture the latency object.
You can pass that option object to the loadTest() function along with a callback function where you get all the performance metrics. I have logged them for information and asserted few metrics based on our requirements.
You can write a similar test for the first api(/ping) and compare the results 🙂
GitHub: https://github.com/rishikeshdhokare/node-performance-testing