<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Executors on Grafana Labs</title><link>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/</link><description>Recent content in Executors on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/k6/v2.3.x/using-k6/scenarios/executors/index.xml" rel="self" type="application/rss+xml"/><item><title>Shared iterations</title><link>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/shared-iterations/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/shared-iterations/</guid><content><![CDATA[&lt;h1 id=&#34;shared-iterations&#34;&gt;Shared iterations&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;shared-iterations&lt;/code&gt; executor shares iterations between the number of VUs.
The test ends once k6 executes all iterations.&lt;/p&gt;
&lt;p&gt;For a shortcut to this executor, use the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/k6-options/reference/#vus&#34;&gt;&lt;code&gt;vus&lt;/code&gt;&lt;/a&gt; and 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/k6-options/reference/#iterations&#34;&gt;&lt;code&gt;iterations&lt;/code&gt;&lt;/a&gt; options.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Iterations &lt;strong&gt;are not guaranteed to be evenly distributed&lt;/strong&gt; with this executor.
VU that executes faster will complete more iterations than slower VUs.&lt;/p&gt;
&lt;p&gt;To guarantee that every VU completes a specific, fixed number of iterations, 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/executors/per-vu-iterations/&#34;&gt;use the per-VU iterations executor&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;options&#34;&gt;Options&lt;/h2&gt;
&lt;p&gt;Besides the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/#options&#34;&gt;common configuration options&lt;/a&gt;,
this executor has the following options:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Option&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
              &lt;th&gt;Default&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;vus&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Number of VUs to run concurrently.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;iterations&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Total number of script iterations to execute across all VUs.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;maxDuration&lt;/td&gt;
              &lt;td&gt;string&lt;/td&gt;
              &lt;td&gt;Maximum scenario duration before it&amp;rsquo;s forcibly stopped (excluding &lt;code&gt;gracefulStop&lt;/code&gt;).&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;&amp;quot;10m&amp;quot;&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;when-to-use&#34;&gt;When to use&lt;/h2&gt;
&lt;p&gt;This executor is suitable when you want a specific number of VUs to complete a fixed
number of total iterations, and the amount of iterations per VU is unimportant.
If the &lt;strong&gt;time to complete&lt;/strong&gt; a number of test iterations is your concern, this executor should perform best.&lt;/p&gt;
&lt;p&gt;An example use case is for quick performance tests in the developement build cycle.
As developers make changes, they might run the test against the local code to test for performance regressions.
Thus the executor works well with a &lt;em&gt;shift-left&lt;/em&gt; policy, where emphasizes testing performance early in the development cycle, when the cost of a fix is lowest.&lt;/p&gt;
&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;p&gt;The following example schedules 200 total iterations shared by 10 VUs with a maximum test duration of 30 seconds.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

export const options = {
  discardResponseBodies: true,
  scenarios: {
    contacts: {
      executor: &amp;#39;shared-iterations&amp;#39;,
      vus: 10,
      iterations: 200,
      maxDuration: &amp;#39;30s&amp;#39;,
    },
  },
};

export default function () {
  http.get(&amp;#39;https://test.k6.io/contacts.php&amp;#39;);
  // Injecting sleep
  // Sleep time is 500ms. Total iteration time is sleep &amp;#43; time to finish request.
  sleep(0.5);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;observations&#34;&gt;Observations&lt;/h2&gt;
&lt;p&gt;The following graph depicts the performance of the &lt;a href=&#34;#example&#34;&gt;example&lt;/a&gt; script:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/k6-oss/shared-iterations.png&#34;
  alt=&#34;Shared Iterations&#34; width=&#34;1662&#34;
     height=&#34;546&#34;/&gt;&lt;/p&gt;
&lt;p&gt;Based upon our test scenario inputs and results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Test is limited to a fixed number of 200 iterations of the &lt;code&gt;default&lt;/code&gt; function;&lt;/li&gt;
&lt;li&gt;The number of VUs is fixed to 10, and are initialized before the test begins;&lt;/li&gt;
&lt;li&gt;Each &lt;em&gt;iteration&lt;/em&gt; of the &lt;code&gt;default&lt;/code&gt; function is expected to be roughly 515ms, or ~2/s;&lt;/li&gt;
&lt;li&gt;Maximum throughput (highest efficiency) is therefore expected to be ~20 iters/s, &lt;code&gt;2 iters/s * 10 VUs&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;The maximum throughput is maintained for a larger portion of the test;&lt;/li&gt;
&lt;li&gt;The distribution of iterations may be skewed: one VU may have performed 50 iterations, another only 10.&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="shared-iterations">Shared iterations&lt;/h1>
&lt;p>The &lt;code>shared-iterations&lt;/code> executor shares iterations between the number of VUs.
The test ends once k6 executes all iterations.&lt;/p>
&lt;p>For a shortcut to this executor, use the
&lt;a href="/docs/k6/v2.3.x/using-k6/k6-options/reference/#vus">&lt;code>vus&lt;/code>&lt;/a> and
&lt;a href="/docs/k6/v2.3.x/using-k6/k6-options/reference/#iterations">&lt;code>iterations&lt;/code>&lt;/a> options.&lt;/p></description></item><item><title>Per VU iterations</title><link>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/per-vu-iterations/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/per-vu-iterations/</guid><content><![CDATA[&lt;h1 id=&#34;per-vu-iterations&#34;&gt;Per VU iterations&lt;/h1&gt;
&lt;p&gt;With the &lt;code&gt;per-vu-iterations&lt;/code&gt; executor, each VU executes an exact number of iterations.
The total number of completed iterations equals &lt;code&gt;vus * iterations&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;options&#34;&gt;Options&lt;/h2&gt;
&lt;p&gt;Besides the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/#options&#34;&gt;common configuration options&lt;/a&gt;,
this executor has the following options:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Option&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
              &lt;th&gt;Default&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;vus&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Number of VUs to run concurrently.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;iterations&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Number of &lt;code&gt;exec&lt;/code&gt; function iterations to be executed by each VU.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;maxDuration&lt;/td&gt;
              &lt;td&gt;string&lt;/td&gt;
              &lt;td&gt;Maximum scenario duration before it&amp;rsquo;s forcibly stopped (excluding &lt;code&gt;gracefulStop&lt;/code&gt;).&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;&amp;quot;10m&amp;quot;&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;when-to-use&#34;&gt;When to use&lt;/h2&gt;
&lt;p&gt;Use this executor if you need a specific number of VUs to complete the same number of
iterations. This can be useful when you have fixed sets of test data that you want to
partition between VUs.&lt;/p&gt;
&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;p&gt;The following example schedules 10 VUs to execute 20 iterations &lt;em&gt;each&lt;/em&gt;.
The test runs 200 total iterations and has a maximum duration of 30 seconds.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

export const options = {
  discardResponseBodies: true,
  scenarios: {
    contacts: {
      executor: &amp;#39;per-vu-iterations&amp;#39;,
      vus: 10,
      iterations: 20,
      maxDuration: &amp;#39;30s&amp;#39;,
    },
  },
};

export default function () {
  http.get(&amp;#39;https://test.k6.io/contacts.php&amp;#39;);
  // Injecting sleep
  // Sleep time is 500ms. Total iteration time is sleep &amp;#43; time to finish request.
  sleep(0.5);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;observations&#34;&gt;Observations&lt;/h2&gt;
&lt;p&gt;The following graph depicts the performance of the &lt;a href=&#34;#example&#34;&gt;example&lt;/a&gt; script:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/k6-oss/per-vu-iterations.png&#34;
  alt=&#34;Per VU Iterations&#34; width=&#34;1654&#34;
     height=&#34;556&#34;/&gt;&lt;/p&gt;
&lt;p&gt;Based upon our test scenario inputs and results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The number of VUs is fixed at 10, and are initialized before the test begins;&lt;/li&gt;
&lt;li&gt;Total iterations are fixed at 20 iterations per VU, i.e. 200 iterations, &lt;code&gt;10 VUs * 20 iters each&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Each &lt;em&gt;iteration&lt;/em&gt; of the &lt;code&gt;default&lt;/code&gt; function is expected to be roughly 515ms, or ~2/s;&lt;/li&gt;
&lt;li&gt;Maximum throughput (highest efficiency) is therefore expected to be ~20 iters/s, &lt;code&gt;2 iters/s * 10 VUs&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;The maximum throughput is reached, but not maintained;&lt;/li&gt;
&lt;li&gt;Because the distribution of iterations is even among VUs, a &lt;em&gt;fast&lt;/em&gt; VU may finish early and be idle for the remainder of the test, thereby lowering &lt;em&gt;efficiency&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;Total duration of 9 seconds is slightly longer than 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/executors/shared-iterations/&#34;&gt;shared iterations&lt;/a&gt; due to lower efficiency;&lt;/li&gt;
&lt;li&gt;Overall test duration lasts as long as the &lt;em&gt;slowest&lt;/em&gt; VU takes to complete 20 requests.&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="per-vu-iterations">Per VU iterations&lt;/h1>
&lt;p>With the &lt;code>per-vu-iterations&lt;/code> executor, each VU executes an exact number of iterations.
The total number of completed iterations equals &lt;code>vus * iterations&lt;/code>.&lt;/p></description></item><item><title>Constant VUs</title><link>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/constant-vus/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/constant-vus/</guid><content><![CDATA[&lt;h1 id=&#34;constant-vus&#34;&gt;Constant VUs&lt;/h1&gt;
&lt;p&gt;With the &lt;code&gt;constant-vus&lt;/code&gt; executor, a fixed number of VUs execute as many iterations as possible for a specified amount of time.&lt;/p&gt;
&lt;p&gt;For a shortcut to this executor, use the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/k6-options/reference/#vus&#34;&gt;VUs&lt;/a&gt; and 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/k6-options/reference/#duration&#34;&gt;duration&lt;/a&gt; options.&lt;/p&gt;
&lt;h2 id=&#34;options&#34;&gt;Options&lt;/h2&gt;
&lt;p&gt;Besides the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/#options&#34;&gt;common configuration options&lt;/a&gt;,
this executor has the following options:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Option&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
              &lt;th&gt;Default&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;duration&lt;sup&gt;(required)&lt;/sup&gt;&lt;/td&gt;
              &lt;td&gt;string&lt;/td&gt;
              &lt;td&gt;Total scenario duration (excluding &lt;code&gt;gracefulStop&lt;/code&gt;).&lt;/td&gt;
              &lt;td&gt;-&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;vus&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Number of VUs to run concurrently.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;when-to-use&#34;&gt;When to use&lt;/h2&gt;
&lt;p&gt;Use this executor if you need a specific number of VUs to run for a certain amount of time.&lt;/p&gt;
&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;p&gt;This examples schedules 10 VUs to run constantly for a duration 30 seconds.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

export const options = {
  discardResponseBodies: true,
  scenarios: {
    contacts: {
      executor: &amp;#39;constant-vus&amp;#39;,
      vus: 10,
      duration: &amp;#39;30s&amp;#39;,
    },
  },
};

export default function () {
  http.get(&amp;#39;https://test.k6.io/contacts.php&amp;#39;);
  // Injecting sleep
  // Total iteration time is sleep &amp;#43; time to finish request.
  sleep(0.5);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;observations&#34;&gt;Observations&lt;/h2&gt;
&lt;p&gt;The following graph depicts the performance of the &lt;a href=&#34;#example&#34;&gt;example&lt;/a&gt; script:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/k6-oss/constant-vus.png&#34;
  alt=&#34;Constant VUs&#34; width=&#34;1682&#34;
     height=&#34;486&#34;/&gt;&lt;/p&gt;
&lt;p&gt;Based upon our test scenario inputs and results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The number of VUs is fixed at 10, and are initialized before the test begins;&lt;/li&gt;
&lt;li&gt;Overall test duration is fixed at the configured 30 second duration;&lt;/li&gt;
&lt;li&gt;Each &lt;em&gt;iteration&lt;/em&gt; of the &lt;code&gt;default&lt;/code&gt; function is expected to be roughly 515ms, or ~2/s;&lt;/li&gt;
&lt;li&gt;Maximum throughput (highest efficiency) is therefore expected to be ~20 iters/s, &lt;code&gt;2 iters/s * 10 VUs&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;We see that the maximum throughput is reached and maintained for the majority of the test;&lt;/li&gt;
&lt;li&gt;Approximately 600 iterations are therefore performed in total, &lt;code&gt;30 seconds * 20 iters/s&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="constant-vus">Constant VUs&lt;/h1>
&lt;p>With the &lt;code>constant-vus&lt;/code> executor, a fixed number of VUs execute as many iterations as possible for a specified amount of time.&lt;/p>
&lt;p>For a shortcut to this executor, use the
&lt;a href="/docs/k6/v2.3.x/using-k6/k6-options/reference/#vus">VUs&lt;/a> and
&lt;a href="/docs/k6/v2.3.x/using-k6/k6-options/reference/#duration">duration&lt;/a> options.&lt;/p></description></item><item><title>Ramping VUs</title><link>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/ramping-vus/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/ramping-vus/</guid><content><![CDATA[&lt;h1 id=&#34;ramping-vus&#34;&gt;Ramping VUs&lt;/h1&gt;
&lt;p&gt;With the &lt;code&gt;ramping-vus&lt;/code&gt; executor, a variable number of VUs executes as many iterations as possible for a specified amount of time.&lt;/p&gt;
&lt;p&gt;For a shortcut to this executor, use the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/k6-options/#stages&#34;&gt;stages&lt;/a&gt; option.&lt;/p&gt;
&lt;h2 id=&#34;options&#34;&gt;Options&lt;/h2&gt;
&lt;p&gt;Besides the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/#options&#34;&gt;common configuration options&lt;/a&gt;,
this executor has the following options:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Option&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
              &lt;th&gt;Default&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;stages&lt;sup&gt;(required)&lt;/sup&gt;&lt;/td&gt;
              &lt;td&gt;array&lt;/td&gt;
              &lt;td&gt;Array of objects that specify the target number of VUs to ramp up or down to.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;startVUs&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Number of VUs to run at test start.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;gracefulRampDown&lt;/td&gt;
              &lt;td&gt;string&lt;/td&gt;
              &lt;td&gt;Time to wait for an already started iteration to finish before stopping it during a ramp down.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;&amp;quot;30s&amp;quot;&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;when-to-use&#34;&gt;When to use&lt;/h2&gt;
&lt;p&gt;This executor is a good fit if you need VUs to ramp up or down during specific periods
of time.&lt;/p&gt;
&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;p&gt;This example schedules a two-stage test, ramping up from 0 to 10 VUs over 20 seconds, then down
to 0 VUs over 10 seconds.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;
import { sleep } from &amp;#39;k6&amp;#39;;

export const options = {
  discardResponseBodies: true,
  scenarios: {
    contacts: {
      executor: &amp;#39;ramping-vus&amp;#39;,
      startVUs: 0,
      stages: [
        { duration: &amp;#39;20s&amp;#39;, target: 10 },
        { duration: &amp;#39;10s&amp;#39;, target: 0 },
      ],
      gracefulRampDown: &amp;#39;0s&amp;#39;,
    },
  },
};

export default function () {
  http.get(&amp;#39;https://test.k6.io/contacts.php&amp;#39;);
  // Injecting sleep
  // Sleep time is 500ms. Total iteration time is sleep &amp;#43; time to finish request.
  sleep(0.5);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;With 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/concepts/graceful-stop/#the-gracefulrampdown&#34;&gt;&lt;code&gt;gracefulRampDown&lt;/code&gt;&lt;/a&gt; set to 0 seconds, some iterations might be
interrupted during the ramp down stage.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;observations&#34;&gt;Observations&lt;/h2&gt;
&lt;p&gt;The following graph depicts the performance of the &lt;a href=&#34;#example&#34;&gt;example&lt;/a&gt; script:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/k6-oss/ramping-vus.png&#34;
  alt=&#34;Ramping VUs&#34; width=&#34;1656&#34;
     height=&#34;600&#34;/&gt;&lt;/p&gt;
&lt;p&gt;Based upon our test scenario inputs and results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The configuration defines 2 stages for a total test duration of 30 seconds;&lt;/li&gt;
&lt;li&gt;Stage 1 ramps &lt;em&gt;up&lt;/em&gt; VUs linearly from the &lt;code&gt;startVUs&lt;/code&gt; of 0 to the target of 10 over a 20 second duration;&lt;/li&gt;
&lt;li&gt;From the 10 VUs at the end of stage 1, stage 2 then ramps &lt;em&gt;down&lt;/em&gt; VUs linearly to the target of 0 over a 10 second duration;&lt;/li&gt;
&lt;li&gt;Each &lt;em&gt;iteration&lt;/em&gt; of the &lt;code&gt;default&lt;/code&gt; function is expected to be roughly 515ms, or ~2/s;&lt;/li&gt;
&lt;li&gt;As the number of VUs changes, the iteration rate directly correlates; each addition of a VU increases the rate by about 2 iters/s, whereas each subtraction of a VU reduces by about 2 iters/s;&lt;/li&gt;
&lt;li&gt;The example performed ~300 iterations over the course of the test.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;get-the-stage-index&#34;&gt;Get the stage index&lt;/h2&gt;
&lt;p&gt;To get the current running stage index, use the &lt;code&gt;getCurrentStageIndex&lt;/code&gt; helper function from the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/jslib/utils/&#34;&gt;k6-jslib-utils&lt;/a&gt; library. It returns a zero-based number equal to the position in the shortcut &lt;code&gt;stages&lt;/code&gt; array or in the executor&amp;rsquo;s &lt;code&gt;stages&lt;/code&gt; array.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { getCurrentStageIndex } from &amp;#39;https://jslib.k6.io/k6-utils/1.3.0/index.js&amp;#39;;

export const options = {
  stages: [
    { target: 10, duration: &amp;#39;30s&amp;#39; },
    { target: 50, duration: &amp;#39;1m&amp;#39; },
    { target: 10, duration: &amp;#39;30s&amp;#39; },
  ],
};

export default function () {
  if (getCurrentStageIndex() === 1) {
    console.log(&amp;#39;Running the second stage where the expected target is 50&amp;#39;);
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Using this feature, it is possible to automatically tag using the current running stage. Check the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/tags-and-groups/#tagging-stages&#34;&gt;Tagging stages&lt;/a&gt; section for more details.&lt;/p&gt;
]]></content><description>&lt;h1 id="ramping-vus">Ramping VUs&lt;/h1>
&lt;p>With the &lt;code>ramping-vus&lt;/code> executor, a variable number of VUs executes as many iterations as possible for a specified amount of time.&lt;/p>
&lt;p>For a shortcut to this executor, use the
&lt;a href="/docs/k6/v2.3.x/using-k6/k6-options/#stages">stages&lt;/a> option.&lt;/p></description></item><item><title>Constant arrival rate</title><link>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/constant-arrival-rate/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/constant-arrival-rate/</guid><content><![CDATA[&lt;h1 id=&#34;constant-arrival-rate&#34;&gt;Constant arrival rate&lt;/h1&gt;
&lt;p&gt;With the &lt;code&gt;constant-arrival-rate&lt;/code&gt; executor, k6 starts a fixed number of iterations over a specified period of time.
It is an open-model executor, meaning iterations start independently of system response (for details, read

    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/concepts/open-vs-closed/&#34;&gt;Open and Closed models&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;This executor continues to start iterations at the given rate as long as VUs are available.
The time to execute an iteration can vary with test logic or the system-under-test response time.
To compensate for this, the executor starts a varied number of VUs to meet the configured iteration rate.
For explanations of how allocation works, read 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/concepts/arrival-rate-vu-allocation/&#34;&gt;Arrival-rate VU allocation&lt;/a&gt;.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Iteration starts are spaced fractionally.&lt;/strong&gt;
Iterations &lt;strong&gt;do not&lt;/strong&gt; start at exactly the same time.
At a &lt;code&gt;rate&lt;/code&gt; of &lt;code&gt;10&lt;/code&gt; with a &lt;code&gt;timeUnit&lt;/code&gt; of &lt;code&gt;1s&lt;/code&gt;, each iteration starts about every tenth of a second (that is, each 100ms).&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;options&#34;&gt;Options&lt;/h2&gt;
&lt;p&gt;Besides the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/#options&#34;&gt;common configuration options&lt;/a&gt;,
this executor has the following options:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Option&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
              &lt;th&gt;Default&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;duration&lt;sup&gt;(required)&lt;/sup&gt;&lt;/td&gt;
              &lt;td&gt;string&lt;/td&gt;
              &lt;td&gt;Total scenario duration (excluding &lt;code&gt;gracefulStop&lt;/code&gt;).&lt;/td&gt;
              &lt;td&gt;-&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;rate&lt;sup&gt;(required)&lt;/sup&gt;&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Number of iterations to start during each &lt;code&gt;timeUnit&lt;/code&gt; period.&lt;/td&gt;
              &lt;td&gt;-&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;preAllocatedVUs&lt;sup&gt;(required)&lt;/sup&gt;&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Number of VUs to pre-allocate before test start to preserve runtime resources.&lt;/td&gt;
              &lt;td&gt;-&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;timeUnit&lt;/td&gt;
              &lt;td&gt;string&lt;/td&gt;
              &lt;td&gt;Period of time to apply the &lt;code&gt;rate&lt;/code&gt; value.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;&amp;quot;1s&amp;quot;&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;maxVUs&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Maximum number of VUs to allow during the test run.&lt;/td&gt;
              &lt;td&gt;If unset, same as &lt;code&gt;preAllocatedVUs&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;when-to-use&#34;&gt;When to use&lt;/h2&gt;
&lt;p&gt;When you want iterations to remain constant, independent of the performance of the system under test.
This approach is useful for a more accurate representation of RPS, for example.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Don&amp;rsquo;t put sleep at the end of an iteration.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The arrival-rate executors already pace the iteration rate through the &lt;code&gt;rate&lt;/code&gt; and &lt;code&gt;timeUnit&lt;/code&gt; properties.
So it&amp;rsquo;s unnecessary to use a &lt;code&gt;sleep()&lt;/code&gt; function at the end of the VU code.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;p&gt;This example schedules a constant rate of 30 iterations per second for 30 seconds.
It pre-allocates 2 VUs, and allows k6 to dynamically schedule up to 50 VUs as needed.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;

export const options = {
  discardResponseBodies: true,
  scenarios: {
    contacts: {
      executor: &amp;#39;constant-arrival-rate&amp;#39;,

      // How long the test lasts
      duration: &amp;#39;30s&amp;#39;,

      // How many iterations per timeUnit
      rate: 30,

      // Start `rate` iterations per second
      timeUnit: &amp;#39;1s&amp;#39;,

      // Pre-allocate 2 VUs before starting the test
      preAllocatedVUs: 2,

      // Spin up a maximum of 50 VUs to sustain the defined
      // constant arrival rate.
      maxVUs: 50,
    },
  },
};

export default function () {
  http.get(&amp;#39;https://test.k6.io/contacts.php&amp;#39;);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;observations&#34;&gt;Observations&lt;/h2&gt;
&lt;p&gt;The following graph depicts the performance of the &lt;a href=&#34;#example&#34;&gt;example&lt;/a&gt; script:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/k6-oss/constant-arrival-rate.png&#34;
  alt=&#34;Ramping VUs&#34; width=&#34;1654&#34;
     height=&#34;562&#34;/&gt;&lt;/p&gt;
&lt;p&gt;Based upon our test scenario inputs and results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The desired rate of 30 iterations started every 1 second is achieved and maintained for the majority of the test.&lt;/li&gt;
&lt;li&gt;The test scenario runs for the specified 30 second duration.&lt;/li&gt;
&lt;li&gt;Having started with 2 VUs (as specified by the &lt;code&gt;preAllocatedVUs&lt;/code&gt; option), k6 automatically adjusts the number of VUs to achieve the desired rate, up to the &lt;code&gt;maxVUs&lt;/code&gt;. For this test, this ended up as 17 VUs.&lt;/li&gt;
&lt;li&gt;The number of VUs to achieve the desired rate varies depending on how long each iteration takes to execute. For this test definition, if it would take exactly 1 second, then 30 VUs would be needed. However, as it takes less than 1 second, then less VUs are needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Using too low of a &lt;code&gt;preAllocatedVUs&lt;/code&gt; setting will reduce the test duration at the desired rate, as resources need to continually be allocated to achieve the rate.&lt;/p&gt;&lt;/blockquote&gt;
]]></content><description>&lt;h1 id="constant-arrival-rate">Constant arrival rate&lt;/h1>
&lt;p>With the &lt;code>constant-arrival-rate&lt;/code> executor, k6 starts a fixed number of iterations over a specified period of time.
It is an open-model executor, meaning iterations start independently of system response (for details, read
&lt;a href="/docs/k6/v2.3.x/using-k6/scenarios/concepts/open-vs-closed/">Open and Closed models&lt;/a>).&lt;/p></description></item><item><title>Ramping arrival rate</title><link>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/ramping-arrival-rate/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/using-k6/scenarios/executors/ramping-arrival-rate/</guid><content><![CDATA[&lt;h1 id=&#34;ramping-arrival-rate&#34;&gt;Ramping arrival rate&lt;/h1&gt;
&lt;p&gt;With the &lt;code&gt;ramping-arrival-rate&lt;/code&gt; executor, k6 starts iterations at a variable rate.
It is an open-model executor, meaning iterations start independently of system response (for details, read

    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/concepts/open-vs-closed/&#34;&gt;Open and Closed models&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;This executor has &lt;em&gt;stages&lt;/em&gt; that configure target number of iterations and the time k6 takes to reach or stay at this target.
Unlike the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/executors/ramping-vus/&#34;&gt;ramping VUs executor&lt;/a&gt;, which configures VUs,
this executor dynamically changes the number of iterations to start, and starts these iterations as long as the test has enough allocated VUs.
To learn how allocation works, read 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/concepts/arrival-rate-vu-allocation/&#34;&gt;Arrival-rate VU allocation&lt;/a&gt;.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Iteration starts are spaced fractionally.&lt;/strong&gt;
Iterations &lt;strong&gt;do not&lt;/strong&gt; start at exactly the same time.
At a &lt;code&gt;rate&lt;/code&gt; of &lt;code&gt;10&lt;/code&gt; with a &lt;code&gt;timeUnit&lt;/code&gt; of &lt;code&gt;1s&lt;/code&gt;, each iteration starts about every tenth of a second (that is, each 100ms).&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;options&#34;&gt;Options&lt;/h2&gt;
&lt;p&gt;Besides the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/#options&#34;&gt;common configuration options&lt;/a&gt;,
this executor has the following options:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Option&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
              &lt;th&gt;Default&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;stages&lt;sup&gt;(required)&lt;/sup&gt;&lt;/td&gt;
              &lt;td&gt;array&lt;/td&gt;
              &lt;td&gt;Array of objects that specify the target number of iterations to ramp up or down to.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;preAllocatedVUs&lt;sup&gt;(required)&lt;/sup&gt;&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Number of VUs to pre-allocate before test start to preserve runtime resources.&lt;/td&gt;
              &lt;td&gt;-&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;startRate&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Number of iterations to execute each &lt;code&gt;timeUnit&lt;/code&gt; period at test start.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;timeUnit&lt;/td&gt;
              &lt;td&gt;string&lt;/td&gt;
              &lt;td&gt;Period of time to apply the &lt;code&gt;startRate&lt;/code&gt; to the &lt;code&gt;stages&lt;/code&gt;&amp;rsquo; &lt;code&gt;target&lt;/code&gt; value. Its value is constant for the whole duration of the scenario, it is not possible to change it for a specific stage.&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;&amp;quot;1s&amp;quot;&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;maxVUs&lt;/td&gt;
              &lt;td&gt;integer&lt;/td&gt;
              &lt;td&gt;Maximum number of VUs to allow during the test run.&lt;/td&gt;
              &lt;td&gt;If unset, same as &lt;code&gt;preAllocatedVUs&lt;/code&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;when-to-use&#34;&gt;When to use&lt;/h2&gt;
&lt;p&gt;If you need start iterations independent of system-under-test performance, and
want to ramp the number of iterations up or down during specific periods of time.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Don&amp;rsquo;t put sleep at the end of an iteration.&lt;/strong&gt;
The arrival-rate executors already pace the iteration rate through the &lt;code&gt;rate&lt;/code&gt; and &lt;code&gt;timeUnit&lt;/code&gt; properties.
It&amp;rsquo;s unnecessary to use a &lt;code&gt;sleep()&lt;/code&gt; function at the end of the VU code.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;p&gt;This is an example of a four-stage test.&lt;/p&gt;
&lt;p&gt;It starts at the defined &lt;code&gt;startRate&lt;/code&gt;, 300 iterations per minute over a one minute period.
After one minute, the iteration rate ramps to 600 iterations started per minute over the next two minutes, and stays at this rate for four more minutes.
In the last two minutes, it ramps down to a target of 60 iterations per minute.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import http from &amp;#39;k6/http&amp;#39;;

export const options = {
  discardResponseBodies: true,

  scenarios: {
    contacts: {
      executor: &amp;#39;ramping-arrival-rate&amp;#39;,

      // Start iterations per `timeUnit`
      startRate: 300,

      // Start `startRate` iterations per minute
      timeUnit: &amp;#39;1m&amp;#39;,

      // Pre-allocate necessary VUs.
      preAllocatedVUs: 50,

      stages: [
        // Start 300 iterations per `timeUnit` for the first minute.
        { target: 300, duration: &amp;#39;1m&amp;#39; },

        // Linearly ramp-up to starting 600 iterations per `timeUnit` over the following two minutes.
        { target: 600, duration: &amp;#39;2m&amp;#39; },

        // Continue starting 600 iterations per `timeUnit` for the following four minutes.
        { target: 600, duration: &amp;#39;4m&amp;#39; },

        // Linearly ramp-down to starting 60 iterations per `timeUnit` over the last two minutes.
        { target: 60, duration: &amp;#39;2m&amp;#39; },
      ],
    },
  },
};

export default function () {
  http.get(&amp;#39;https://test.k6.io/contacts.php&amp;#39;);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;observations&#34;&gt;Observations&lt;/h2&gt;
&lt;p&gt;The following graph depicts the performance of the &lt;a href=&#34;#example&#34;&gt;example&lt;/a&gt; script:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/k6-oss/ramping-arrival-rate.png&#34;
  alt=&#34;Ramping Arrival Rate&#34; width=&#34;2093&#34;
     height=&#34;488&#34;/&gt;&lt;/p&gt;
&lt;p&gt;Based upon our test scenario inputs and results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The configuration defines 4 stages for a total test duration of 9 minutes.&lt;/li&gt;
&lt;li&gt;Stage 1 maintains the &lt;code&gt;startRate&lt;/code&gt; iteration rate at 300 iterations started per minute for 1 minute.&lt;/li&gt;
&lt;li&gt;Stage 2 ramps &lt;em&gt;up&lt;/em&gt; the iteration rate linearly from the &lt;em&gt;stage 1&lt;/em&gt; of 300 iterations started per minute, to the target of 600 iterations started per minute over a 2-minute duration.&lt;/li&gt;
&lt;li&gt;Stage 3 maintains the &lt;em&gt;stage 2&lt;/em&gt; iteration rate at 600 iterations started per minute over a 4-minute duration.&lt;/li&gt;
&lt;li&gt;Stage 4 ramps &lt;em&gt;down&lt;/em&gt; the iteration rate linearly to the target rate of 60 iterations started per minute over the last two minutes duration.&lt;/li&gt;
&lt;li&gt;Changes to the iteration rate are performed by k6, adjusting the number of VUs&lt;/li&gt;
&lt;li&gt;The script waits for a period of time (defined by the &lt;code&gt;gracefulStop&lt;/code&gt; option) for iterations to finish. It doesn&amp;rsquo;t start new iterations during the &lt;code&gt;gracefulStop&lt;/code&gt; period.&lt;/li&gt;
&lt;li&gt;Our example performed, 4020 iterations over the course of the test.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;get-the-stage-index&#34;&gt;Get the stage index&lt;/h2&gt;
&lt;p&gt;To get the current running stage index, use the &lt;code&gt;getCurrentStageIndex&lt;/code&gt; helper function from the 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/jslib/utils/&#34;&gt;k6-jslib-utils&lt;/a&gt; library. It returns a zero-based number equal to the position in the shortcut &lt;code&gt;stages&lt;/code&gt; array or in the executor&amp;rsquo;s &lt;code&gt;stages&lt;/code&gt; array.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { getCurrentStageIndex } from &amp;#39;https://jslib.k6.io/k6-utils/1.3.0/index.js&amp;#39;;

export const options = {
  stages: [
    { target: 10, duration: &amp;#39;30s&amp;#39; },
    { target: 50, duration: &amp;#39;1m&amp;#39; },
    { target: 10, duration: &amp;#39;30s&amp;#39; },
  ],
};

export default function () {
  if (getCurrentStageIndex() === 1) {
    console.log(&amp;#39;Running the second stage where the expected target is 50&amp;#39;);
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Using this feature, it is possible to automatically tag using the current running stage. Check the 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/tags-and-groups/#tagging-stages&#34;&gt;Tagging stages&lt;/a&gt; section for more details.&lt;/p&gt;
]]></content><description>&lt;h1 id="ramping-arrival-rate">Ramping arrival rate&lt;/h1>
&lt;p>With the &lt;code>ramping-arrival-rate&lt;/code> executor, k6 starts iterations at a variable rate.
It is an open-model executor, meaning iterations start independently of system response (for details, read
&lt;a href="/docs/k6/v2.3.x/using-k6/scenarios/concepts/open-vs-closed/">Open and Closed models&lt;/a>).&lt;/p></description></item></channel></rss>