Can we sleep in milliseconds in k6 scripts?

I know the sleep(t) function exists, but only exists in seconds. Can we use default javascript functions such as setTimeout if I wanted to wait for approx 400ms (in this case between two api calls being made in the default function.

I know those aren’t technically “sleeps” but is there any reliable way to “wait” for a time in milliseconds?

edit: It looks like timers does exist and appears to work. Right now my code looks like this (i’ve made it more basic looking for clarity):

export default () => {
http.patch(firstURL,body,params)
setTimeout(() => {
  const res = http.post(secondURL,body,params)
  console.log(res.status)
}, "400");
}

So it does appear to wait around 400ms. However I am curious on one thing. Since setTimeout is an async function, does the default function itself wait for the timeout to end before “ending” that VU’s execution.

IE for a VU that runs this thread does it work like this:

  1. Start Default Function
  2. Do first HTTP Request (against firstURL)
  3. Wait 400ms
  4. While it’s waiting end the default function
  5. Some other thread finishes the HTTP request against secondURL?

or will it wait for the secondURL to finish and the setTimeout Function to finish before ending the default function?

Hi @mercfh

Yes. The iteration (one execution of the “default” function) waits until there is nothing that should be executed to finish the iteration.

in your particular case you are mixing async and syncrhouns APIs which is … not great idea.

both http.patch and http.post predate k6 having an event loop, promises or async/await syntax support.

As such they will block the execution until they return.

setTimeout on the other hand will return immediately and then later call the code.

You can use http.asyncRequest to have asynchronous http request. Or if your script does not need that you can just use sleep instead of setTimeout.

You might also want to import and us a small helper function I have written to work with k6 to delay execution asynchronously.

A “somewhat” full example using async/await syntax:

import http from "k6/http";
import { delay } from "https://gist.githubusercontent.com/mstoykov/7684bf54a1e2f35d048868ba6117e2cb/raw/d44e15a1a942c8aafb9e7a4f7c0d623214b3a651/delay.js";
export default async function() {
   await http.asyncRequest("PATCH", firstURL,body,params)
   await delay(400);
   const res = await http.asyncRequest("POST", secondURL,body,params)
   console.log(res.status)
}

Hope this helps you!!!

p.s. I would also recommend not putting numbers in strings :wink:

1 Like

Yeah I made a mistake with the string formatted time for setTimeout. I don’t need this to be async necessarily I just need to make it where one request happens exactly 400ms after another.

sleep is perfect for this. However according to the docs sleep only accepts seconds, so I assume I cannot do sleep(.4) for example.

I realize my code example isn’t great, but it’s the only way so far I can “sorta” replicate a 400ms sleep to then execute the 2nd request.

sleep is perfect for this. However according to the docs sleep only accepts seconds, so I assume I cannot do sleep(.4) for example.

Numbers in js are floats by default. And sleep works with floats <1.

general tip: You can run code you are wondering about and see how it works.

1 Like

Oh thats even better. And yeah good point I should’ve just tried it (but it’s hard to test exactly so I wanted to confirm that it actually "could’ work like that by asking here)

1 Like