Skip to content
Owais Khan Software Reviews
How-To Guides

What is a k6 Stress Test and How to Implement It

Learn what a k6 stress test is, how to configure one with JavaScript, and see a practical example. Discover k6's unique features for performance testing.

By Owais Khan

A k6 stress test is a type of performance test executed using the k6 open-source load testing tool, designed to determine the breaking point of an application or system by gradually increasing the load beyond its expected capacity [1, 2]. The goal is to identify how the system behaves under extreme conditions and where its stability degrades [1].

Understanding a Standard k6 Load Test Script

Before diving into stress testing, it’s helpful to understand a basic k6 script for general load testing. k6 is an open-source, developer-friendly performance testing tool that uses JavaScript for scripting tests [2, 3]. It allows engineering teams to test the reliability and performance of applications and infrastructure [2]. A typical k6 script defines virtual users (VUs), test duration, and the actions those VUs perform, such as making HTTP requests [3].

Here’s an example of a k6 script configured for a standard load test, aiming to verify an application can handle expected traffic [1]:

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

export const options = {
 vus: 10, // 10 virtual users
 duration: '30s', // Test runs for 30 seconds
 thresholds: {
 'http_req_duration': ['p(95)<500'], // 95% of requests must complete within 500ms
 'http_req_failed': ['rate<0.01'], // Less than 1% of requests should fail
 },
};

export default function () {
 let res = http.get('https://example.com/api/data');
 check(res, {
 'status is 200': (r) => r.status === 200,
 });
 sleep(1); // Simulate user think time
}
  • vus: 10: This sets a constant number of 10 virtual users throughout the test [3].
  • duration: '30s': The test will run for a fixed period of 30 seconds [3].
  • thresholds: These define performance goals, like response time and error rates, which help determine if the test passes or fails [3].
  • http.get('https://example.com/api/data'): This is a simulated action, where a virtual user makes an HTTP GET request to a specific endpoint [1, 3].
  • sleep(1): This pauses the virtual user for 1 second, simulating a user’s “think time” between actions [1, 3].

This script verifies performance under a known, expected load [1].

Transforming a Script for a k6 Stress Test

To conduct a k6 stress test, the primary modification involves configuring the test to gradually increase the number of virtual users (VUs) beyond the system’s anticipated capacity, often until performance degrades significantly or the system fails [1, 2]. This is typically achieved using the stages option in k6, which allows for defining a ramp-up and ramp-down of VUs over time [3].

Here’s the previous script adapted for a stress test:

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

export const options = {
 stages: [
 { duration: '1m', target: 50 }, // Ramp up to 50 VUs over 1 minute (expected load)
 { duration: '2m', target: 200 }, // Ramp up to 200 VUs over 2 minutes (stress phase)
 { duration: '1m', target: 0 }, // Ramp down to 0 VUs over 1 minute
 ],
 thresholds: {
 'http_req_duration': ['p(90)<1000'], // 90% of requests within 1000ms (more lenient for stress)
 'http_req_failed': ['rate<0.05'], // Less than 5% of requests should fail (more lenient for stress)
 },
};

export default function () {
 let res = http.get('https://example.com/api/data');
 check(res, {
 'status is 200': (r) => r.status === 200,
 });
 sleep(0.5); // Shorter sleep to increase request rate per VU
}

Deconstructing the Stress Test Modifications

The key changes from a standard load test to a stress test in k6 revolve around how the load is generated and the expectations for system behavior.

  1. stages Configuration for Load Generation:
  • Instead of a fixed vus and duration, the stages option is used to define a series of steps where the number of virtual users (target) changes over a specified duration [3].
  • In the example, the first stage ramps up to 50 VUs, which might be the expected peak load. The second stage then pushes the system further by ramping up to 200 VUs. This target value of 200 VUs is intentionally set to exceed the system’s known capacity, simulating extreme conditions [1, 2].
  • The final stage ramps down to 0 VUs, allowing the system to recover and providing insights into its post-stress behavior.
  • This progressive increase in load is fundamental to stress testing, as it helps identify the exact point at which the system begins to degrade or fail [1].
  1. Adjusted thresholds for Stress Scenarios:
  • For a stress test, performance thresholds are often more lenient or are used to observe when and how the system breaks, rather than strictly passing or failing based on typical performance metrics [3].
  • In the example, p(90)<1000 for http_req_duration and rate<0.05 for http_req_failed are more relaxed than in a standard load test. This acknowledges that under stress, response times will likely increase, and error rates might rise. The goal is to see how much they rise before the system becomes unusable [1].
  • Thresholds in stress tests can also be configured to trigger alerts when certain critical failure points are reached, indicating the system’s breaking point [3].
  1. Simulated User Behavior (sleep):
  • The sleep duration might be adjusted to control the request rate per virtual user. A shorter sleep(0.5) in the stress test example means each virtual user makes requests more frequently, further contributing to the overall load [1, 3]. This helps to quickly push the system to its limits.

By implementing these changes, a k6 script transforms from verifying performance under expected load to actively seeking out the system’s breaking points and observing its behavior under duress. This helps engineering teams prevent failures and improve reliability by understanding scalability limits [1].

Applying Stress Testing to Your Own k6 Scripts

To convert your own k6 load test script into a stress test, follow these general steps:

  1. Identify Your Baseline Load: Determine the typical or expected maximum number of concurrent users your application should handle. This will be your starting point for the stress test.
  2. Define Stress Stages:
  • Replace fixed vus and duration options with the stages array [3].
  • Start with a stage that ramps up to your baseline load.
  • Add subsequent stages that progressively increase the target VUs well beyond your baseline, pushing into unknown territory. For example, if your baseline is 50 VUs, you might add stages targeting 100, 150, 200 VUs, or even higher, depending on how aggressively you want to find the breaking point [1, 2].
  • Consider adding a final ramp-down stage to observe system recovery [3].
  • Example stages structure:
stages: [
{ duration: '2m', target: 50 }, // Ramp up to expected load
{ duration: '3m', target: 150 }, // Push beyond expected load
{ duration: '2m', target: 0 }, // Ramp down
],
  1. Adjust Thresholds for Observation:
  • Modify your thresholds to reflect the goals of a stress test. Instead of strict pass/fail criteria for optimal performance, you might set thresholds to identify when performance starts to degrade significantly (e.g., p(99) > 5000 for response time, or http_req_failed: ['rate > 0.10'] to detect high error rates) [3]. The purpose is to pinpoint the breaking point.
  1. Review User Behavior Logic:
  • Evaluate the sleep duration and other actions within your default function. For stress testing, you might reduce sleep times to generate a higher request rate per virtual user, accelerating the process of stressing the system [1, 3].
  • Ensure your script accurately reflects critical user journeys that, when stressed, would reveal system vulnerabilities.
  1. Run and Analyze:
  • Execute your modified k6 script using the k6 CLI: k6 run your_stress_test.js [1].
  • Monitor system resources (CPU, memory, network I/O, database performance) on the application servers during the test.
  • Analyze the k6 output metrics, paying close attention to response times, error rates, and throughput as the load increases. Look for sharp increases in errors or response times, or decreases in throughput, which indicate the system’s breaking point.
  • For complex scenarios or to quickly generate test scripts from existing traffic, you can use a HAR (HTTP Archive) file. The HAR to k6 Converter can help you transform recorded browser sessions into k6 scripts, saving manual scripting effort.

k6 as a Modern Performance Testing Tool

k6 is an open-source performance testing tool designed for engineering teams, emphasizing a developer-friendly experience [1, 2, 3]. It is built with Go for performance and allows test scripts to be written in JavaScript, combining the efficiency of Go with the familiarity of JavaScript for many developers [3].

Key aspects that highlight k6’s modern approach include:

  • Tests as Code: k6 promotes writing tests as code, enabling version control, modularization, and seamless integration into CI/CD pipelines for continuous testing [1, 3]. This “shift-left” approach helps catch performance issues early [1, 2].
  • Extensibility: k6 is highly extensible, supporting various protocols like HTTP, WebSockets, gRPC, and browser-based testing [1, 3]. Its extension ecosystem allows users to add new capabilities or integrate with specific infrastructure components [2, 3].
  • Resource Efficiency: k6 is optimized for minimal resource consumption, making it efficient for running high-load tests even on lower-end machines [2, 3].
  • Flexible Deployment: Tests can be run locally, in a distributed manner across Kubernetes clusters, or in the cloud using Grafana Cloud k6, offering scalability from solo developers to large enterprises [1, 3].

Differentiating k6 from Kubernetes (K8s)

While both k6 and Kubernetes (often abbreviated as K8s) are tools used in modern software development, they serve fundamentally different purposes:

  • k6: k6 is a load testing tool [1, 2]. Its primary function is to simulate traffic and measure the performance and reliability of applications and infrastructure under various loads, including stress tests [1, 2]. It helps identify bottlenecks, verify scalability, and ensure applications can handle expected and unexpected traffic [1].
  • Kubernetes (K8s): Kubernetes is an orchestration platform that manages workloads and services, ensuring applications run efficiently and reliably across a cluster of machines [1].

The relationship between k6 and Kubernetes is complementary:

  • Deployment Target: k6 can be used to test applications running on Kubernetes [1]. For instance, you might deploy your application on a Kubernetes cluster and then use k6 to stress test it, observing how the cluster scales and manages resources under load [1].
  • Test Execution Environment: k6 tests themselves can be executed within a Kubernetes environment [1]. This allows for distributed load generation, where multiple k6 instances run as pods within Kubernetes to generate massive amounts of traffic from various locations, simulating real global traffic patterns [1]. The command kubectl apply -f k6.yaml k8s demonstrates running k6 tests on Kubernetes [1].
  • Fault Injection: k6 can also be integrated with Kubernetes for chaos and resilience testing, allowing faults to be injected into Kubernetes-based applications to test their tolerance of internal errors [1, 2].

In essence, k6 is the tool for generating and measuring load, while Kubernetes is the platform for managing and running applications and, optionally, the k6 tests themselves.

Why k6 is a Modern Choice for Performance Testing

Rather than stating k6 is “better” than other tools, it’s more accurate to highlight the specific advantages and design philosophies that make k6 a compelling and modern choice for performance testing, as described in the sources:

  • Developer-Centric Experience: k6 is built with a focus on providing the “best developer experience” for load testing [1, 3]. Its use of JavaScript for scripting makes it accessible to a wide range of developers who are already familiar with the language, reducing the learning curve [1, 3].
  • Performance and Efficiency: Built on Go, k6 is “optimized for minimal resource consumption” and designed for “running high-load performance tests” [2, 3]. This allows it to simulate a large number of virtual users and requests efficiently, even on less powerful machines [3].
  • Integration with Modern DevOps Workflows: k6 is designed to integrate seamlessly into CI/CD pipelines, promoting “shift-left” performance testing where tests are run early and continuously [1, 2]. This enables engineering teams to automate performance testing as part of their development and release cycle, preventing regressions from reaching production [1, 2].
  • Extensibility and Flexibility: k6 is highly extensible, supporting a wide array of protocols (HTTP, WebSockets, gRPC, browser testing) and offering an extension ecosystem [1, 2, 3]. This allows it to adapt to diverse testing needs and integrate with various developer tools and monitoring systems like Grafana, Prometheus, and Datadog [1].
  • Cloud-Native Capabilities: With native integration with Grafana Cloud k6, it offers a SaaS solution for test execution, metrics correlation, and data analysis, supporting distributed tests from multiple load zones to simulate global traffic patterns [1, 3].

These characteristics position k6 as a powerful and adaptable tool for modern engineering teams focused on building resilient and high-performing applications [2].

Open the HAR to k6 Converter

Frequently asked questions

What is the primary goal of a k6 stress test?
The primary goal of a k6 stress test is to determine the breaking point of an application or system by pushing it beyond its normal operating capacity, identifying how it behaves under extreme load, and where its stability degrades [1, 2].
How does k6 help prevent failures?
k6 helps prevent failures by enabling engineering teams to test scalability, improve reliability targets, and proactively catch performance issues early and continuously, thus preventing regressions from reaching production [1, 2].
Can k6 be used for different types of performance tests?
Yes, k6 is designed for load testing and is extensible to support various types of performance tests, including stress tests, spike tests, soak tests, and smoke tests, each with different goals [1, 2].
What programming language is used for k6 scripts?
k6 test scripts are written in JavaScript, providing a familiar and developer-friendly experience for defining test logic and scenarios [1, 3].
Where can k6 tests be executed?
k6 tests can be executed locally on your machine, in a distributed manner across Kubernetes clusters, or in the cloud using Grafana Cloud k6, allowing for flexible deployment options [1, 3].
What is a k6 threshold?
A k6 threshold is a pass/fail criterion defined in the test script, such as a maximum response time or an acceptable error rate, that determines whether the performance test meets its defined goals [3].