How to limit the number of API methods calls in test?

Hello, guys!
I am newbie in k6. Could you help me with a support request ? I need to test three different API methods sequentially under the same user. Each of these methods must be called once. The test should be run once a minute. I have already configured the vus parameter to limit the number of users, but the API methods are called several times during the test run. What parameter should I use to limit the number of method calls ? The screenshot below shows the results of the test.

Hi @Daniil,
the way k6 works is that it does as many iterations of the default function as fast as possible.
From what see, I can only guess that you are running for a duration of 2 seconds and manage to finish 2 iterations and do 7 requests. I would expect the 7th request to be the first in the 3rd iteration but your test runs out of time as you have specified 2 seconds.

If what you want is to do 1 iteration you can instead of specifying duration:2s (doc) to specify iterations:1 (doc). This will mean that k6 will do 1 iteration and then stop. Alternatively (especially if you want to run this for a long time) you can specify minIterationDuration: 60s (doc). This will mean that every time an iteration is finished k6 will check if it took at least minIterationDuration and wait/sleep for the remaining time.

More info about options can be find in the documentation.

1 Like

@mstoykov, much appreciate for your help. I’ll make changes to my test.

@mstoykov,
I checked documentation and I have one more question about test duration. Could you clarify, can i set total test time for my test (for example: 5 minutes) and repeat my actions after each minute until the test is completed ?

If you configure duration: 5min and minIterationDuration:60s, each VU (no matter how many you’ve configured, if there is no iterations configured) will start 1 iteration right away. When it finishes it will check if since the beginning of the iteration 60seconds have passed and if not sleep for the rest. If 60 seconds have passed it will just continue and make another iteration directly.
The duration:5min will mean that after 5min the whole k6 process will start stopping so with that configuration you will at most finish 4 iterations per VU as when the time comes for them to start the 5th the whole k6 process will start shutting down and they will stopped.

If you are doing some kind of monitoring and want this script to run forever I would recommend disabling the summary(--no-summary) and thresholds (--no-thresholds) as that will eat a lot of memory in the long run and also running with some duration such as 1000000000000s which will be around 30k years :smiley: . Alternatively you can just start a new process every 1 minute, if your script is simple enough and you use 1 VU this might be sufficiently fast.
Although I guess if you will be making 2-3 request a minute the memory will raise pretty slowly even if you keep thresholds and summary enabled, you will probably need to test and see if the memory increase over 24hours is too big … although again if you are doing 1/min and 3requests/iteration that would probably not be a problem :wink:

If on the other hand you want to do X number of iterations with N number of times between them on a single VU, I would argue you should do iterations:X and minDuration:N.

@mstoykov, thank you again for your help.

1 Like

@mstoykov,

I’m sorry for bother you again. I have one more question about counter metric. In my test i need to send request with different tokens. I’ve created a counter in default function and pass counter into my authorize function. I’ve expected that in each iteration for each vu token will be different, but unfortunately it doesn’t that. Could you tell me which mechanism is better to use for this case ?

Here is my default function body and authorize function :

    export default function() {
    let accessToken = "";
    var counter = 0;
	group("authorization", function() {
		var res = authorize(counter);
		check(res, {
			"status is 200 OK": (res) => res.status === 200,
			"content-type is application/json": (res) => res.headers['Content-Type'] === "application/json; charset=utf-8",
			"login successful, accessToken is not empty": (res) => JSON.parse(res.body).hasOwnProperty('AccessToken')
		});
		accessToken = JSON.parse(res.body).AccessToken;
		myTrend.add(res.timings.duration);
	});

	group("upcoming", function(){
	    var res = getUpcoming(true);
	    check(res, {
	        "status is 200 OK": (res) => res.status === 200,
	        "content-type is application/json": (res) => res.headers['Content-Type'] === "application/json; charset=utf-8",
	        "events count is equal 10": (res) => JSON.parse(res.body).Result.EventsCount === 10,
	    });
        placeObj = parseUpcomingResp(res);
	    myTrend.add(res.timings.duration);
	});
  group("placeBet", function(){
	    var res = placeBet(accessToken, placeObj);
	    check(res, {
	        "status is 200 OK": (res) => res.status === 200,
	        "content-type is application/json": (res) => res.headers['Content-Type'] === "application/json; charset=utf-8"
	    });
	    myTrend.add(res.timings.duration);
	});
};


export function authorize(counter, debug) {
    var token = "[regex|load]load-" + counter;
    console.log('authorize token: ' + token);
    let walletCode = "914205";
	let url = mainUrl + "/Auth/SignIn";
	var signInBody = { timezoneOffset: '-180', langId: '8', skinName: 'default', configId: 1,
	 culture: 'en-GB', countryCode: '', numFormat: 'en', Token: token, WalletCode: walletCode, country: 'en-us' };
    var json = JSON.stringify(signInBody);
	var resp = http.post(url, json, { headers: {"Content-Type": "application/json"}});
	counter++;
	if (typeof debug !== 'undefined')
		console.log("authorize: status=" + String(resp.status) + "  Body=" + resp.body);
	return resp;
};

Hi Daniil,

meanwhile in trying to figuring out how to work with trends and limiting your number of API requests, you can have have a look at our blog post about the same topic. Hope it helps!

How to generate a constant request rate in k6?

@mostafa, thank you.
But I’m looking how to implement a unique counter for each VU to unify each of tokens i use for my signIn requests.

Then, have a look at execution context variables to help with the unique counter.

1 Like