Limits RPS when we have more than one request in the function

Hello,

I’m writting here because I am not able to find a solution to my problem with k6 in other posts.

I have a script like this:

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

export let options = {
  vus: 10, 
  duration: '1m', 
  rps: 100
};

export default function () {
  // Llamada GET #1
  http.get('https://tu-api.com/endpoint1');

  // Espera entre llamadas
  sleep(1);

  // Llamada GET #2
  http.get('https://tu-api.com/endpoint2');

  // Llamada GET #3
  http.get('https://tu-api.com/endpoint3');

}

I want to limit the request per MINUTE to 90. ¿Is it possible?

Every example that I see on the internet talks about using arrival-rate executors, but this executors uses iterations insted of RPS. Also, every example shows only 1 request inside the function, so with only 1 request, is easy because iterations/sec = requests/sec.

But what happens when there are more than 1 request? How can I achieve the exact RPS?

The --rps command only admits integer values, so I’m limited to 60 per minute, or 120 per minute, but not 90.

With JMeter, the Precise Throughput Timer was flexible to put seconds or minutes, so we were able to achieve this. How can I do it with k6? I’m learning.

Thanks a lot.

Bye.

Hi @fdenis, welcome to the community forum!

You’re right, --rps only accepts integer values.

I have two ideas to solve your issue:

Idea 1
If you know, that there are 3 request per iteration, then you can use the constant-arrival-rate executor like this:

export const options = {
  scenarios: {
    contacts: {
      executor: 'constant-arrival-rate',
      duration: '1m',
      rate: 30,
      timeUnit: '1m',
      preAllocatedVUs: 10,
    },
  },
};

this will create 30 iterations per minute, which will execute 90 requests per minute.

Idea 2
Although usage of request rate limiter is not recomended (as documentation states: Options reference), you can create an extension that overwrites the rate limiter with a new one, which accepts float value also.

I created a PoC extension for this:

Hi bandorko,

I really appreciate your fast answer. Thanks.

In the Idea 1, what happens if the requests takes too much time to answer? I mean, imagine a case that each request took 45 seconds.

If k6 creates 30 iterations, in 1 minute will send 60 requests. So to achieve the 90, i will have to create 45 iterations per minute. That’s because I know exactly the time that the request will take. But what happens if the first one took 45s, but the second and the third took 1s?

The 45 iterations will send 135 requests (too much). And the 30 iterations, will match now the 90rps that I wanted.

In a real scenario, I can’t predice how much time a request will take, so it’s hard to use iterations in that case, isn’t it?

The solution that I had in JMeter when you want to limit the RPS, is start as many VUs that you want, and then limit the RPS (using minutes or seconds).

What I’m trying to say, and sorry if I am misunderstanding something, is that I would be able to use “Idea 1” only if I know how much a request will take, or if the requests doesn’t take too much time. So the only way to achieve this is using RPS (Idea 2).

Is it correct?

Again, sorry if I am misunderstanding something, and I appreciate your patience.

Thanks again.

@fdenis

In your example for the idea 1, you’re right for the first minute of test run only.
Let’s simplify further your example and assume, that every request takes 1 minutes to complete. If you set 30 iterations/minute, then in the first minute k6 will start 30 iterations which will execute 30 requests. In the second minute because of the first 30 iterations is still running, and k6 tries to keep the 30 iterations/minutes, another 30 iterations will be started. In the second minute 60 VUs are running, which will execute 60 requests in the second minute. From the third minute on k6 will execute 90 requests per minute. So if you run your script long enough rps will aproach to 90 requests/minute

1 Like