Need help in understanding maxVUs in ramping-arrival-rate executor

I ran the following script file to understand ramping arrival rate executor.

Command was k6 run fix-rpm-testing.js

export const options = {
  scenarios: {
    testing:{
      executor: 'ramping-arrival-rate',
      startRate: 100,
      timeUnit: '1m',
      preAllocatedVUs: 1,
      maxVUs: 2,
      stages: [
        { target: 100, duration: '1m' }
      ]
    }
  }
};

export default function (data) {}

And here is my console output


          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io

  execution: local
     script: fix-rpm-testing.js
     output: -

  scenarios: (100.00%) 1 scenario, 2 max VUs, 1m30s max duration (incl. graceful stop):
           * testing: Up to 1.67 iterations/s for 1m0s over 1 stages (maxVUs: 1-2, gracefulStop: 30s)


running (1m00.0s), 0/1 VUs, 99 complete and 0 interrupted iterations
testing ✓ [======================================] 0/1 VUs  1m0s  2 iters/s

     data_received........: 0 B 0 B/s
     data_sent............: 0 B 0 B/s
     iteration_duration...: avg=10.85µs min=5.17µs med=10.52µs max=49.92µs p(90)=12.37µs p(95)=27.14µs
     iterations...........: 99  1.649874/s
     vus..................: 1   min=1      max=1
     vus_max..............: 1   min=1      max=1

What is the reason for 99 iterations instead of targeted value 100 even though I specified maxVUs:2 and it shows vus_max=1 ?

Does that mean K6 never created 2nd VU even though it was unable to reach the target of 100 iteration ?

When I ran your script a few times, I actually got 100 iterations most of the attempts. Whether you get exactly 100 iterations or 99 depends on minute timing differences in how k6 schedules these iterations. With your config, it will attempt to make one new iteration every 600ms, for up to 60 seconds. But for the hundredth iteration, due to a bit slower startup or something like that, it might try to start it at t=60s1ms, it’s a race between starting it at exactly t=60s and the scenario ending at exactly t=60s. Some times one “wins”, other times the other wins.

The second VU doesn’t matter, since it was never needed - even one VU is enough to run an empty iteration every 600ms :sweat_smile:

Try running this script, it will give you more clarity about what’s going on under the hood:

import exec from 'k6/execution';

export const options = {
    scenarios: {
        testing: {
            executor: 'ramping-arrival-rate',
            startRate: 100,
            timeUnit: '1m',
            preAllocatedVUs: 1,
            maxVUs: 2,
            stages: [
                { target: 100, duration: '1m1ms' }
            ]
        }
    }
};

export default function () {
    console.log(`[t=${(new Date()) - exec.scenario.startTime}ms] VU{${exec.vu.idInTest}} ran iteration ${exec.scenario.iterationInTest}`);
}
2 Likes

Thanks @ned for the reply :+1: