Examining System Performance Based on Real-Life Load Conditions

Matheus Leal
Nerd For Tech
Published in
6 min readMay 24, 2021

--

Consider the following scenarios: During festive seasons or a promotion period, e-commerce may experience an increase in accesses; Enrollment or registration updates campaigns, with deadlines; When a blog is cited by a major newspaper. These and other scenarios may push your systems to the limit or even exceed it. One of the most effective ways to identify and prevent this kind of problem is to perform a performance test. This term refers to tests that will measure the performance of an application. Different methods exist to achieve this goal. The objective of this article is to examine the possibilities to determine system stability based on real-life load conditions.

Performance Testing Services — Qrapp Technology

You may have already experienced a situation where you see an ad for an online sale with discounts up to 80%. Imagine also that the product that you wanted to buy was also advertised in the promotion. Immediately, you pick up your cell phone, search on Google, try to access it, but the site doesn’t load. You refresh the page thinking that the problem is with your connection, but you still have no access. You retry until you get tired of waiting and give up on the purchase.

The situation above is more common than you might think. This is an example of a performance problem that affects various websites. One of the most effective ways to identify and prevent this kind of problem is to perform a performance test. By doing so, it is possible to determine which transactions may impact the application’s execution, defining the minimum architecture configuration that will allow the software to meet what was specified, minimizing the risks related to the performance requirements.

The objective of this text is to examine the possibilities to determine the system stability based on real-life load conditions. We are going to present a solution using k6 as our load testing engine.

Performance Testing

The terms “peak”, “endurance”, “load” and “stress” are often used to describe tests that try to understand how the software performs during the performance of a given task. In general, all of these terms refer to tests that will measure the performance of an application, but each of them uses different methods to achieve this goal.

Types of performance test — Retrive from Abstracta

Each of these performance tests has its advantages. It is important to identify the purpose of your test to define which type to apply:

  • Load Testing: involves evaluating the performance of a system under the expected workload.
  • Endurance Testing: determine if the system can sustain the continuous expected load for a long duration.
  • Stress Testing: evaluate the application’s performance at a load much higher than the expected workload.
  • Peak Testing: analyze the behavior of the system on suddenly increasing the number of users.

Load Testing

Load testing is performed to determine a system’s behavior under normal and anticipated peak load conditions. It helps to identify the maximum operating capacity of an application as well as any bottlenecks that might cause degradation. When the load placed on the system is raised beyond normal usage patterns to test the system’s response at unusually high or peak loads, it is known as stress testing.

The popular load testing tools provide insights into the causes for slow performance. There are numerous possible causes for slow system performance, including, but not limited to, the following:

  • Application server(s) or software
  • Database server(s)
  • Network (latency, congestion, etc)
  • Client-side processing
  • Load balancing between multiple servers

A prerequisite for successful load testing is having goals. For example, above what level is a response time not acceptable, and/or what is an acceptable request failure rate. It is also a good practice to make sure that your load testing is functionally correct.

K6

k6 is an open-source load testing tool built for making load testing an easy practice. Using it, you’ll be able to catch performance regression and problems earlier, allowing you to build resilient systems and robust applications. Key features include:

  • CLI tool
  • Scripting in JavaScript
  • Possibility for automatic load testing

k6 users are typically Developers, QA and DevOps Engineers. They use k6 for testing the performance of APIs, microservices, and websites. Common k6 use cases are:

  • Load testing: Designed to run tests with high load in pre-production and QA environments.
  • Monitoring: You can run tests with a small amount of load to continuously monitor the performance of your production environment.

The company behind the service has also a commercial option to run in the cloud. With this SaaS it is possible to scale tests from multiple locations, get actionable performance insights and scheduling tests.

Use case

The most basic type of load testing is used to determine the behavior of the Web under normal conditions and high levels of load. As the load test begins, it is recommended to start with a small number of virtual users and then gradually increase the load from normal to the peak.

Load testing workflow — Retrive from linhadecodigo

We are going to present some scenarios of Load Testing using k6 as our tool. Our tests will be performed locally. First, you will need to install the binary. The situation will be a simple test for HTTP requests. As you can see in the block below, we have built a .js script with the configuration necessary for our test. We can stipulate the stages of our test (ramp up/down patterns) through the options object. Performance and functional goals can be codified using thresholds and checks. Also, note that we are saving the response to res, which can be accessed later.

import http from 'k6/http';import { sleep, check } from 'k6';import { Counter } from 'k6/metrics';
export const requests = new Counter('http_reqs');export const options = { stages: [ { target: 20, duration: '1m' }, { target: 15, duration: '1m' }, { target: 0, duration: '1m' }, ], thresholds: { requests: ['count < 100'], },};export default function () { const res = http.get('http://test.k6.io'); sleep(1); const checkRes = check(res, { 'status is 200': (r) => r.status === 200, 'response body': (r) => r.body.indexOf('Feel free to browse') !== -1, });}

To start the experiment just run the following command:

$ k6 run single-request.js          /\      |‾‾| /‾‾/   /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io
execution: local
script: single-request.js
output: -
scenarios: (100.00%) 1 scenario, 20 max VUs, 3m30s max duration (incl. graceful stop):
* default: Up to 20 looping VUs for 3m0s over 3 stages (gracefulRampDown: 30s, gracefulStop: 30s)

At the end it displays the results:

default ✓ [======================================] 00/20 VUs  3m0s     ✓ status is 200
✗ response body
↳ 0% — ✓ 0 / ✗ 1871
checks.........................: 50.00% ✓ 1871 ✗ 1871
data_received..................: 21 MB 117 kB/s
data_sent......................: 142 kB 788 B/s
http_req_blocked...............: avg=1.64ms min=2µs med=4µs max=192.17ms p(90)=6µs p(95)=8µs
http_req_connecting............: avg=1.62ms min=0s med=0s max=192.11ms p(90)=0s p(95)=0s
http_req_duration..............: avg=156.27ms min=138.97ms med=152.57ms max=426.66ms p(90)=167.92ms p(95)=172.34ms
{ expected_response:true }...: avg=156.27ms min=138.97ms med=152.57ms max=426.66ms p(90)=167.92ms p(95)=172.34ms
http_req_failed................: 0.00% ✓ 0 ✗ 1871
http_req_receiving.............: avg=236.51µs min=43µs med=116µs max=21.17ms p(90)=425µs p(95)=801.5µs
http_req_sending...............: avg=21.6µs min=8µs med=20µs max=158µs p(90)=27µs p(95)=32µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=156.01ms min=138.83ms med=152.32ms max=426.18ms p(90)=167.71ms p(95)=171.52ms
http_reqs......................: 1871 10.374419/s
iteration_duration.............: avg=1.15s min=1.13s med=1.15s max=1.42s p(90)=1.17s p(95)=1.17s
iterations.....................: 1871 10.374419/s
vus............................: 1 min=1 max=20
vus_max........................: 20 min=20 max=20

As we can see, the service by default already collects relevant information that helps to evaluate the performance of the application. with it we can identify latency, number of simultaneous virtual users and data related to requests made. In its official documentation, you can find more tutorials and examples.

Conclusion

The objective of this article is to examine the possibilities to ascertain system stability based on real-life load conditions. The terms “peak”, “endurance”, “load” and “stress” are often used to describe tests that try to understand how the software performs during the performance of a given task. More specifically, load testing is performed to determine a system’s behavior under both normal and anticipated peak load conditions. We present a solution using k6, an open-source load testing tool. Using it, developers, QA and DevOps Engineers can intercept performance problems earlier, allowing them to build resilient systems and robust applications.

--

--

Matheus Leal
Nerd For Tech

M.Sc at Pontifícia Universidade Católica do Rio de Janeiro & Applying DevOps culture at Globo