Getting Started6 min readFebruary 25, 2025

Load Profiles: Constant, Ramp, Spike, and Soak Tests

Not all load tests are equal. Learn when to use each load shape and how to configure them in k6.

By Perfscale Team

The four load test types

Each pattern is designed to answer a different question:

PatternQuestion answered
Smoke testDoes the app work at all under minimal load?
Load testDoes it meet SLOs at expected production load?
Stress / spike testWhat happens at 2× or 10× normal load?
Soak testDoes it degrade over time under sustained load?

Smoke test

A quick sanity check — a handful of VUs for a short time.

export const options = {
  vus: 3,
  duration: '1m',
  thresholds: {
    http_req_failed: ['rate<0.01'],
  },
};

When to run: Every PR, before a deployment, after an incident.


Load test (constant rate)

Simulates steady-state production traffic.

export const options = {
  scenarios: {
    steady_load: {
      executor: 'constant-arrival-rate',
      rate: 500,          // 500 requests per second
      timeUnit: '1s',
      duration: '10m',
      preAllocatedVUs: 50,
    },
  },
  thresholds: {
    http_req_duration: ['p(95)<200'],
    http_req_failed:   ['rate<0.005'],
  },
};

Use constant-arrival-rate instead of constant-vus for meaningful throughput targets — VU-based tests produce variable RPS as latency changes.


Ramp-up test

Gradually increases load to find the breaking point.

export const options = {
  stages: [
    { duration: '2m', target: 100 },   // ramp to 100 VUs
    { duration: '5m', target: 100 },   // hold
    { duration: '2m', target: 500 },   // ramp to 500 VUs
    { duration: '5m', target: 500 },   // hold
    { duration: '2m', target: 1000 },  // ramp to 1000 VUs
    { duration: '5m', target: 1000 },  // hold
    { duration: '2m', target: 0 },     // ramp down
  ],
};

Watch the p99 latency chart. The point where it starts climbing steeply is your practical capacity.


Spike test

An instant jump to 10× normal load — simulates flash sales, news events, bot traffic.

export const options = {
  stages: [
    { duration: '30s', target: 50 },    // normal load
    { duration: '10s', target: 5000 },  // SPIKE
    { duration: '3m',  target: 5000 },  // hold the spike
    { duration: '10s', target: 50 },    // back to normal
    { duration: '3m',  target: 50 },    // recovery check
  ],
};

Key question: does the service recover after the spike, or does latency stay elevated?


Soak test

24–72 hours at moderate load. Catches memory leaks, connection pool exhaustion, disk fill.

export const options = {
  stages: [
    { duration: '5m',  target: 200 },
    { duration: '24h', target: 200 },  // hold for 24 hours
    { duration: '5m',  target: 0 },
  ],
  thresholds: {
    http_req_duration: ['p(99)<1000'],  // more lenient SLO for long runs
  },
};

Warning: Don't run soak tests against production unless you're certain about the load level.


Combining patterns

A complete test suite typically runs all four:

On every PR:    smoke test (3 VUs, 1 min)
Nightly:        load test  (steady production load, 15 min)
Pre-release:    stress test (ramp to 3× production, find breaking point)
Weekly:         soak test  (production load, 2 hours)

This covers correctness, SLO, capacity, and long-term stability in a single automated pipeline.