Slide 4 of 9

Designing a realistic load profile

Load profile shape

A baseline load profile has three phases.

Load profile diagram showing ramp-up, steady state, and ramp-down

PhasePurposeDuration
Ramp-upGradually increase VUs to avoid cold-start spikes30 seconds to 1 minute
Steady stateHold at target load to collect stable metrics1-2 minutes minimum
Ramp-downReduce VUs back to zero for clean shutdown30 seconds

Scenarios, executors, and stages

k6 uses scenarios to describe how a test runs. Each scenario picks an executor that schedules virtual users or iteration rate. The ramping-vus executor changes the target number of VUs over time using a stages array, which matches the ramp-up, steady-state, and ramp-down idea above.

Putting stages on the root options object is a shortcut for a single scenario that uses the ramping-vus executor. For several traffic shapes in one script, or when you want scenario names in results, configure the scenarios object explicitly instead.

Example: shortcut with stages

JavaScript
export const options = {
  stages: [
    { duration: '30s', target: 20 },  // ramp up
    { duration: '1m',  target: 20 },  // steady state
    { duration: '30s', target: 0 },   // ramp down
  ],
};

Example: explicit scenario with ramping-vus

JavaScript
export const options = {
  scenarios: {
    baseline: {
      executor: 'ramping-vus',
      stages: [
        { duration: '30s', target: 20 },
        { duration: '1m',  target: 20 },
        { duration: '30s', target: 0 },
      ],
    },
  },
};

Choosing your VU count

Match VUs to observed or expected concurrency for the traffic slice you are baselining, not an arbitrary round number. If you do not yet have production metrics, start from staging access logs or product assumptions, then adjust after you see stable http_req_duration and error rate in the steady-state window.

If your profile uses ramping-vus, the target in each stage is the number of VUs k6 tries to schedule; combined with iteration time, that determines how much load you actually generate. For a deliberately constant request rate instead, you would pick an arrival-rate executor; refer to API load testing: request rate. This course stays on ramping VUs because it matches the baseline paths you run next.

A baseline measures normal behavior; deliberately exceeding your production concurrency belongs in stress or load-test scenarios covered in the k6 test types guide after you have a baseline.

Script

A load profile defines how many virtual users hit your system and for how long. The key to a useful baseline is making this profile realistic. Real traffic doesn’t jump from zero to full load instantly. Users arrive gradually, maintain a steady level, and taper off.

In k6, workload is organized into scenarios, and each scenario uses an executor that decides how virtual users or iteration rate change over time. Stages are the timed steps used by the ramping-vus executor to ramp target virtual users up, hold steady, and ramp down. A typical baseline profile has three phases in those stages: ramp-up, steady state, and ramp-down. The ramp-up gradually increases virtual users to avoid shocking the system. The steady state holds at your target load long enough to collect stable metrics. The ramp-down brings virtual users back to zero.

The steady state phase is where your baseline metrics come from. You want it long enough to produce statistically meaningful data, usually at least one to two minutes at the target virtual user count.

The virtual user count itself should reflect realistic production traffic. If your system typically handles 20 concurrent users, that’s your baseline target. Testing at 100 virtual users when you normally have 20 isn’t a baseline test, it’s a stress test.