Ramping-arrival-rate preallocated vs vumax usage

Hey folks. I’ve been fighting with myself for awhile about a philosophical technical question. when using ramping arrival rate I have typically been setting the preallocated vu param to 0 then setting my theoretical maxvu to whatever value I think is needed for the VU capacity to maintain throughput. well I read somewhere that preallocated should be used for better vu utilization. don’t ask where I don’t remember. but this seemed odd to me. so I asked one of favorite GenAI tools the following. It of course agrees with my current usage of preallocated vs vumax :slight_smile:

what say ye community what is “generally” the best way to manage vu usage with this executory?

Given the scenario you’ve described - driving thousands of transactions per second for 30 minutes or more - let’s analyze the two approaches for applying VUs (Virtual Users) in k6:

  1. Preallocating maximum VUs:

    preAllocatedVUs: v2_authorize_code_106_gate_rush_vumax,
    maxVUs: v2_authorize_code_106_gate_rush_vumax,
    
  2. Setting maxVUs to maximum capacity and preAllocatedVUs to 0:

    preAllocatedVUs: 0,
    maxVUs: v2_authorize_code_106_gate_rush_vumax,
    

For your high-throughput, extended duration scenario, the second approach (setting maxVUs and preAllocatedVUs to 0) is generally the better choice. Here’s why:

  1. Resource Efficiency:
    By setting preAllocatedVUs to 0, k6 will dynamically allocate VUs as needed. This is more resource-efficient, especially at the start of the test when the rate is low (your startRate is 0).

  2. Scalability:
    The ramping-arrival-rate executor you’re using will automatically scale up the number of VUs as needed to meet the target rate. Setting preAllocatedVUs to 0 allows this scaling to happen smoothly from the beginning.

  3. Warm-up Period:
    With preAllocatedVUs: 0, you allow for a natural warm-up period as VUs are added gradually. This can be beneficial for some systems under test, preventing an initial spike of load.

  4. Memory Management:
    Preallocating a large number of VUs can consume a significant amount of memory right from the start. By starting with 0 preallocated VUs, you allow k6 to manage memory more efficiently, only using what’s necessary as the test progresses.

  5. Flexibility:
    This setup provides more flexibility if you need to adjust your test parameters. It’s easier to increase maxVUs if needed without worrying about the initial allocation.

However, there are a couple of points to consider:

  1. VU Initialization Time:
    There might be a slight overhead as new VUs are initialized during the test. In most cases, this is negligible, especially for a long-running test like yours.

  2. Consistent High Load:
    If you know you’ll quickly ramp up to maximum capacity and stay there, preallocating VUs could provide a marginal performance benefit. But for a ramping scenario like yours, this benefit is likely outweighed by the advantages of dynamic allocation.

Given your specific scenario with a ramping arrival rate starting from 0, running for an extended period, and potentially reaching thousands of transactions per second, the approach of setting preAllocatedVUs: 0 and maxVUs: v2_authorize_code_106_gate_rush_vumax is indeed the better choice. It provides a good balance of resource efficiency, scalability, and flexibility for your high-throughput, extended-duration load test.

Hi @PlayStay,

Welcome back to our community! :tada:

Thanks for bringing such a nice topic, as I feel your likely not the only one wondering about this. So, let me try to summarize how I understand it.

There are, of course, very specific scenarios where the memory consumption per VU is heavy, but generally speaking, I’d say that the recommendation is to try to set a preAllocatedVUs value as close as possible to the total amount of VUs required to reach the desired rate.

Why? Because, unless you’re in one of the scenarios I mentioned above, in general the memory consumption per VU is quite more negligible than the impact of allocating new VUs. So, if you set a preAllocatedVUs value that is far from the amount required to reach the desired rate, what would happen is that k6 would keep some time during the test (or per stage) adjusting the amount of VUs, which could make the test results less reliable, because:

  • During that time, the rate isn’t the desired one.
  • Some CPU cycles are spent on allocating new VUs, impacting the overall performance.

That’s why in general, and in docs, maxVUs are questioned (see you probably dont need maxVUs). Unless, you’re in one of the scenarios described there, as situations where it might make sense to use maxVUs:

  • To determine necessary allocation in first-time tests, when you don’t know yet what value set to preAllocatedVUs but you want to define a “hard-limit”.
  • To add a little “cushion” to the pre-allocated VUs that you expect the test needs, so complementary to preAllocatedVUs, but always assuming that preAllocatedVUs is also set to a meaningful value.
  • In huge, highly distributed tests, in which you need to carefully scale load generators as you increment VUs, for instance, in memory-heavy load tests, where the amount of required VUs to reach the desired rate is considerably different over the execution of the test -stages- and you want to avoid some initial allocations extra.

I hope that helps you clarifying a bit what’s the purpose of maxVUs and why is generally speaking discouraged, and generally better trying to configure the preAllocatedVUs as close as possible to the amount of VUs required to reach the desired rate.

But, if that’s not the case, and you still have doubts or specific questions, I’ll be more than happy to try to help you in this thinking process :bowing_man:

Regards,
Joan

1 Like