In most cases, when users start to access and use a new application or a new release, app performs pretty well. As the user base grows and usage increases, the app can outgrow its infrastructure. Users can start experiencing a dip in performance. Latency increases, bandwidth and memory get exhausted quickly, and some code architectures start to fail because they do not scale well with the increased amount of users. This is not an unexpected issue; infrastructure and application architecture are meant to scale with increased usage. The risk is not knowing ahead of time when the application will ‘break’ or when the infrastructure will go down because there is increased load on the server. This issue can lead to big losses especially in financial terms.
Load testing is one of the most important kinds of testing in the software application lifecycle. With load tests, you can subject your application to the type of pressures expected in production. That gives you the information to fine-tune infrastructure and architectures, making sure that your application does not dip below your performance thresholds.
In this tutorial, we will be load testing a simple Node.js API using Apache benchmark, a load testing and benchmarking tool for HTTP servers.
To follow this tutorial, a few things are required:
- Node.js installed on your system (version >= 10.3)
- A Heroku account
- A CircleCI account
- A GitHub account
With all these installed and set up, we can begin the tutorial.
Setting up Heroku for hosting
The first step is to set up a Heroku application to host our API. Navigate to your Heroku apps dashboard. Click New, then Create new app. Using the name you prefer, create a new app.
Take note of the app name (
node-loadtest here) you just entered. You will need this later on during the tutorial.
Next, locate your Heroku API Key in the
Account Settings section of your dashboard.
You will also need this later in the tutorial.
Cloning the test project
For the next step, you will need to clone the API project. The API project is a simple Node.js API application with a root endpoint and another endpoint for fetching a collection of users. Clone the project by running this command:
git clone --single-branch --branch base-project https://github.com/coderonfleek/node-loadtest
Once the cloning process is complete, go into the root of the project and install the dependencies by running these commands:
cd node-loadtest npm install
When the installation is complete, run the application with the command:
The application will start listening on a default port of
3000. Open up Postman and make a
GET request to the
http://localhost:3000/users/get endpoint. This should return an array of users.
Result? The API seems to be working fine.
Connecting to CircleCI
To set up the API project on CircleCI, you first need to push the project to GitHub.
Next, go to the Projects page on the CircleCI dashboard (Select the appropriate GitHub account) to add the project.
Click the Set Up Project button to begin. This will load the next screen.
On the setup page, click Use Existing Config to instruct CircleCI that we are adding a configuration file manually and not using the sample displayed. Next, you will be prompted to either download a configuration file for the pipeline or to start building.
Click Start Building. This build will fail because we have not set up our configuration file yet. We will complete this step later on.
The final thing we need to do on the CircleCI console is to set up environment variables for the project we just added. This will enable our project to have authenticated access to our Heroku application for deployments.
Go to your project’s settings by clicking the Project Settings button on the Pipelines page. Make sure your project is the currently selected project.
On the Project Settings page, click Environment Variables (it is in the side menu).
On the Environment Variables page, click Add Environment Variable.
Add the following environment variables:
HEROKU_APP_NAMEis the name of your Heroku application (in this case
HEROKU_API_KEYis your Heroku account API key (mentioned earlier).
You now have everything set up on your CircleCI console for deployment to Heroku.
Adding the load test in the pipeline configuration
It is now time to build the deployment pipeline that will load test the API’s
/users/get endpoint each time a deployment is made. At the root of your project, create a folder named
.circleci and a file named
config.yml within it. Inside
config.yml, enter this code:
jobs: build: executor: heroku/default steps: - checkout - heroku/install - heroku/deploy-via-git loadtestapi: docker: - image: circleci/node:10.16.3 steps: - run: name: Run Load Test command: | sudo apt-get update sudo apt-get install apache2-utils ab -k -c 20 -n 250 https://$HEROKU_APP_NAME.herokuapp.com/users/get orbs: heroku: email@example.com version: 2.1 workflows: deploy: jobs: - build - loadtestapi: requires: - build
In the configuration you just created, there are two jobs:
buildjob uses CircleCI’s Heroku orb to deploy the API project from the GitHub repository to the Heroku app created on the hosting platform
Once the API is deployed, the
loadtestapiinstalls the Apache benchmark tool then uses the tool to send
250requests to the
/users/getendpoint using a concurrency of
Keep-Aliveconnection type for a persistent connection with the
Using workflows, the
loadtestapi job will not run until the
build job is complete, ensuring that we do not run the load test until the API is successfully deployed.
Time to run the load test pipeline. Commit all changes to the project and push to your remote Github repository. This will automatically trigger the pipeline and you should have a successful build.
loadtestapi job in the workflow to review the results of the load test.
The results show that all
250 requests were served within
0.44 seconds. Whether this is a good result or not depends on the performance metrics set for your application by you or by your organization. Other details are shown that detail how the tests ran. These details can be useful in tuning your application architecture to better scale for thousands to millions of users using the application.
Any enterprise or startup organization serving software to users should take load tests seriously. Load testing enables you to avoid the consequences of downtime while users make use of the application. In this tutorial, we have been able to deploy an API and immediately run a load test to verify its capability to handle web traffic. There are many ways to extend these load tests using Apache benchmark. There are also specialized tools that can be plugged into the process or used as a replacement for Apache benchmark, like k6.
Fikayo Adepoju is a LinkedIn Learning (Lynda.com) Author, Full-stack developer, technical writer, and tech content creator proficient in Web and Mobile technologies and DevOps with over 10 years experience developing scalable distributed applications. With over 40 articles written for CircleCI, Twilio, Auth0, and The New Stack blogs, and also on his personal Medium page, he loves to share his knowledge to as many developers as would benefit from it. You can also check out his video courses on Udemy.