k6 spike tests are your secret weapon for understanding how your system behaves when traffic suddenly explodes.

Here’s what a k6 spike test looks like in action. Imagine you have a baseline load of 100 virtual users that runs for 5 minutes, and then you want to suddenly blast that up to 1000 users for just 1 minute before dropping back down.

import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  stages: [
    { duration: '5m', target: 100 }, // Ramp up to 100 users over 5 minutes
    { duration: '1m', target: 1000 }, // Spike to 1000 users for 1 minute
    { duration: '5m', target: 100 },  // Ramp down to 100 users over 5 minutes
    { duration: '3m', target: 0 },   // Ramp down to 0 users over 3 minutes
  ],
};

export default function () {
  http.get('https://your-api-endpoint.com/resource');
  sleep(1);
}

This stages array is where the magic happens. You define a series of target user loads and the duration each load should be maintained. k6 then interpolates the user count between these stages.

The primary problem spike tests solve is uncovering the "breaking point" of your system under extreme, short-lived load. Think flash sales, viral social media posts, or sudden DDoS attacks (though for actual DDoS, you’d use specialized tools). While gradual load tests show how your system handles increasing load, spike tests reveal its resilience to sudden, unexpected bursts. This often exposes issues like:

  • Connection Pool Exhaustion: When a sudden influx of requests overwhelms the available database or upstream service connections.
  • Resource Starvation: CPU, memory, or disk I/O bottlenecks that only appear under peak, transient demand.
  • Queue Overloads: Message queues or internal application queues that can’t process messages fast enough during a surge, leading to backlogs and eventual timeouts.
  • Caching Invalidation/Thundering Herd: When a cache is cleared or misses occur simultaneously for a large number of requests, leading to a massive load on the origin.
  • Load Balancer/API Gateway Limits: Edge services that might have rate limits or connection limits that get hit during a spike.

The stages option in k6 is incredibly flexible. You can define multiple spikes, varying durations, and different target user counts within a single test run. This allows for complex scenarios that mimic real-world traffic patterns more closely.

For instance, if you anticipate a major product launch followed by a smaller, secondary surge later, you could configure stages like this:

export const options = {
  stages: [
    { duration: '2m', target: 50 },   // Initial steady state
    { duration: '30s', target: 2000 }, // First major spike
    { duration: '5m', target: 100 },  // Recovery/baseline
    { duration: '1m', target: 800 },  // Secondary spike
    { duration: '10m', target: 50 },  // Long tail
    { duration: '2m', target: 0 },    // Cool down
  ],
};

The key is to map your expected traffic surges as accurately as possible to the stages configuration.

When a spike test reveals performance degradation or failures, it’s often due to how quickly system resources can scale or how gracefully queues and connection pools handle sudden demand. A system that scales horizontally very quickly might handle a spike well, while one that relies on slower vertical scaling or has fixed connection limits might buckle.

The most surprising thing about spike testing is how often the first bottleneck you encounter isn’t at your application’s core, but in a seemingly ancillary service like DNS resolution or a third-party API dependency that hasn’t provisioned enough capacity for your sudden burst. You might be looking at your database metrics and see no issues, only to find that your application is timing out waiting for a response from an external service that’s struggling to keep up.

The next step after understanding how to simulate traffic surges is to analyze the resulting failure modes and implement strategies for graceful degradation or rapid auto-scaling.

Want structured learning?

Take the full K6 course →