Skip to content

Latest commit

 

History

History
181 lines (139 loc) · 6.86 KB

File metadata and controls

181 lines (139 loc) · 6.86 KB

Ramping VUs Executor

As noted in Setting load profiles with executors, the Ramping VUs executor primarily focuses on the number of virtual users (VUs) within stages.

Exercises

For our exercises, we're going to start by using a very basic script that simply performs an HTTP request and then waits one second before completing the test iteration. We're providing some console output as things change.

Creating our script

Let's begin by implementing our test script. Create a file named test.js with the following content:

import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  scenarios: {
    k6_workshop: {
      executor: 'ramping-vus',
      stages: [
        { target: 10, duration: "30s" },
      ],
    },
  },
};

export default function () {
  console.log(`[VU: ${__VU}, iteration: ${__ITER}] Starting iteration...`);
  http.get('https://test.k6.io/contacts.php');
  sleep(1);
}

Our "basic" script is a little more complicated than some of our previous examples. This is due to the need to define stages in addition to the executor itself. At least a single stage is required, each of which includes a target and duration option, both of which are also required.

Initial test run

Let's go ahead and run our script using the k6 CLI:

k6 run test.js

Looking at the output from the script, you should see that several virtual users (VUs) performed test iterations over a 30-second period.

INFO[0029] [VU: 2, iteration: 18] Starting iteration...  source=console
INFO[0029] [VU: 7, iteration: 2] Starting iteration...   source=console
INFO[0029] [VU: 4, iteration: 21] Starting iteration...  source=console
INFO[0029] [VU: 6, iteration: 15] Starting iteration...  source=console
INFO[0030] [VU: 5, iteration: 12] Starting iteration...  source=console

running (0m31.0s), 00/10 VUs, 141 complete and 0 interrupted iterations
k6_workshop ✓ [======================================] 00/10 VUs  30s

☝️ The iteration counter is 0-based, meaning a count of 12 is actually 13 iterations.

A closer inspection at the iteration counts may seem odd. The counts seem to be all over the board: VU #7 only performed 3 iterations, while VU #4 performed 22. As with the Constant VUs executor, each virtual user executes the default function () continuously, so how can there be such a disparity?

This disparity in iteration counts is due to the ramping aspect of the executor. k6 will linearly scale up or down the number of running VUs to achieve the target number of VUs defined within the stage. The duration will determine how long the scaling with take place.

Because we did not specify a startVUs option, k6 used the default value of 1. Therefore, our test started with a single VU, then ramped up to 10 VUs over a period of 30 seconds. For this reason, we may then infer that VU #7 became active much later in the stage than VU #4.

VUs
   
10 |                                .......
   |                        ......./
 5 |                ......./
   |        ......./
 1 |......./
   +---------------------------------------+ 30s
                 S T A G E  # 1    

Inverse the slope

Let's invert the slope of our test by changing our startVUs and the target for the stage. We'll update the options in our test script as follows:

export const options = {
  scenarios: {
    k6_workshop: {
      executor: 'ramping-vus',
      stages: [
        { target: 1, duration: "30s" },
      ],
      startVUs: 10,
    },
  },
};
INFO[0026] [VU: 3, iteration: 24] Starting iteration...  source=console
INFO[0027] [VU: 6, iteration: 25] Starting iteration...  source=console
INFO[0027] [VU: 7, iteration: 25] Starting iteration...  source=console
INFO[0028] [VU: 6, iteration: 26] Starting iteration...  source=console
INFO[0028] [VU: 7, iteration: 26] Starting iteration...  source=console
INFO[0029] [VU: 6, iteration: 27] Starting iteration...  source=console
INFO[0029] [VU: 7, iteration: 27] Starting iteration...  source=console

running (0m30.5s), 00/10 VUs, 168 complete and 0 interrupted iterations
k6_workshop ✓ [======================================] 00/10 VUs  30s

This time, you can see the number of VUs performing a higher count of iterations diminishes over the duration.

VUs
   
10 |.......
   |       \.......
 5 |               \.......
   |                       \.......
 1 |                               \.......
   +---------------------------------------+ 30s
                 S T A G E  # 1    

When ramping down VUs as we did in this last exercise, k6 provides some flexibility when reclaiming resources. By default, VUs targeted for removal are given a 30-second grace period during which to complete the current iteration it may be working on. This grace period may be adjusted using the gracefulRampDown option to fine-tune the value if necessary.

Simulate spikes in active users

The real power of ramping is the ability to simulate activity spikes. This can be done by defining multiple stages.

VUs
                   
10 |                 .  
   |                / \ 
 5 |               /   \
   |              /     \............      
 1 |............./                              
   +------------+---+---+------------+ 30s
        #1        #2  #3       #4

From our lovely ASCII art diagram, we'll modify our script to run 4 stages to simulate a spike in virtual users. Let's alter our startVUs, first stage, and add new stages to our simulation:

export const options = {
  scenarios: {
    k6_workshop: {
      executor: 'ramping-vus',
      stages: [
        { target: 1, duration: "12s" },
        { target: 10, duration: "3s" },
        { target: 3, duration: "3s" },
        { target: 3, duration: "12s" },
      ],
      startVUs: 1,
    },
  },
};

Run the script once more:

k6 run test.js

Now, you should notice that the test starts slowly, then ramps up quickly as the spike occurs, then ramps down to a moderate pace until the end of the test.

INFO[0028] [VU: 3, iteration: 26] Starting iteration...  source=console
INFO[0028] [VU: 2, iteration: 14] Starting iteration...  source=console
INFO[0028] [VU: 7, iteration: 15] Starting iteration...  source=console
INFO[0029] [VU: 3, iteration: 27] Starting iteration...  source=console
INFO[0029] [VU: 2, iteration: 15] Starting iteration...  source=console
INFO[0029] [VU: 7, iteration: 16] Starting iteration...  source=console

running (0m30.7s), 00/10 VUs, 80 complete and 0 interrupted iterations
k6_workshop ✓ [======================================] 00/10 VUs  30s

Wrapping up

With this exercise, you should be able to see the power of being able to ramp up and down the number of VUs in order to model your test activity.