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 most cases, new applications perform pretty well. But as the user base grows and usage increases, an app can outgrow its infrastructure. Users can start experiencing a decline in performance. Latency increases and bandwidth and memory get exhausted quickly. Some code architectures start to fail because they do not scale well with the increased amount of user activity.

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, in both financial terms and customer confidence.

In this tutorial, you will learn how to implement load testing on a simple Node.js API using ApacheBench (ab), a load testing and benchmarking tool for HTTP servers. You will use a CircleCI continuous integration and continuous deployment (CI/CD) pipeline to automatically deploy and load test updates to your API.

Prerequisites

To follow this tutorial, a few things are required:

  1. Basic knowledge of JavaScript
  2. Node.js installed on your system (version >= 18)
  3. A Heroku account
  4. A CircleCI account
  5. A GitHub account

Our tutorials are platform-agnostic, but use CircleCI as an example. If you don’t have a CircleCI account, sign up for a free one here.

Setting up Heroku for hosting

The first step is to set up a Heroku application to host your API. Go to your Heroku apps dashboard. Click New, then Create new app. Decide on a name, then create the new app.

New app - Heroku

Take note of the app name (node-load-tests 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 to copy your API Key from this page 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/CIRCLECI-GWP/load-tests-node-apis.git

Once the cloning process is complete, go into the root of the project and install the dependencies:

cd load-tests-node-apis
npm install

When the installation is complete, run the application:

npm start

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 or check that link using your favorite browser. This should return an array of users.

Get users - browser

Result? The API seems to be working fine.

Adding configuration file

In this step, you will configure the CI/CD pipeline that will automatically deploy your application to Heroku. This script also load tests 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:

version: 2.1

orbs:
  node: circleci/node@5.1.1
jobs:
  build-and-deploy:
    docker:
      - image: "cimg/base:stable"
    steps:
      - checkout
      - node/install
      - run:
          command: npm install
          name: Install dependencies
      - run:
          name: Deploy app to Heroku
          command: |
            git push https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git main

  load-test-api:
    docker:
      - image: "cimg/base:stable"
    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>-<RANDOM_NUMBER>.herokuapp.com/users/get

workflows:
  deploy:
    jobs:
      - build-and-deploy
      - load-test-api:
          requires:
            - build-and-deploy

In the configuration you just created, there are two jobs:

  • The build-and-deploy job uses Git to deploy the API project from the GitHub repository to the Heroku app created on the hosting platform.
  • Once the API is deployed, the load-test-api job installs the ApacheBench tool then uses it to send 250 requests to the /users/get endpoint using a concurrency of 20 and a Keep-Alive connection type for a persistent connection with the -k flag.

Using workflows, the load-test-api job will not run until the build-and-deploy job is complete. This ensures that you do not run the load test until the API is successfully deployed.

Note: Replace https://<HEROKU_APP_NAME>-<RANDOM_NUMBER>.herokuapp.com with your Heroku app URL.

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.

Your next task is to get a project set up on CircleCI. Begin by pushing your project to GitHub.

Next, log into your CircleCI account. If you signed up with your GitHub account, all your repositories will be available on your project’s dashboard.

Click Set Up Project next to your load-tests-node-apis project.

Select project

You will be prompted to enter the name of the branch your configuration file is on. Click Set Up Project once you are done. This will trigger your first workflow, which will fail.

The deployment process fails because you have not provided your Heroku API key. To fix that, click the Project Settings button, then click Environment Variables. Add these two new variables:

  • For HEROKU_APP_NAME, add the app name you used in Heroku. The name will be either node-load-tests or a custom name if you created one.
  • For HEROKU_API_KEY enter the Heroku API key that you retrieved earlier from the account settings page.

Re-run your workflow from the start, and this time your workflow will run successfully.

Build successful - CircleCI

Click the loadtestapi job in the workflow to review the results of the load test.

Build details - CircleCI

The results show that all 250 requests were served within 0.165 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 data is shown that details how the tests ran. These details can be useful in tuning your application architecture to better scale for thousands to millions of users on your application.

Conclusion

Any enterprise or startup organization serving software to users should take load tests seriously. Load testing enables you to avoid the consequences of user downtime while customer are performing critical work, or important fun.

In this tutorial, you have learned 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 ApacheBench. There are also specialized tools that can be plugged into the process or used as a replacement for ApacheBench, like k6. For an example, check out API performance testing with k6.

Happy coding!


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.

Read more posts by Fikayo Adepoju