DEV Community

Cover image for K6 - Modern load testing
Darlan GuimarĂŁes
Darlan GuimarĂŁes

Posted on

K6 - Modern load testing

Hey, devs! đź‘‹

Today I'm bringing a summary about K6 from Grafana Labs, an open-source performance testing software, which could be considered a replacement for JMeter, with some unique characteristics.

Defined as an advanced load testing tool that makes performance testing more accessible and integrated into the development workflow. It fills the gap between traditional load testing and modern development practices.

Load Test Types

K6 supports various test types for different scenarios:

A performance test results screen showing HTTP request metrics. The test was successful with 100% checks passed (168/168), received 24 MB of data, and sent 41 kB. Various HTTP request metrics are displayed including response times, durations, and connection stats. The test ran for 31.9 seconds with 2 VUs (Virtual Users) and completed 56 iterations.

  • Smoke Tests: Quick checks for basic system stability
  • Average-load test: Simulating typical user traffic
  • Stress tests: Taking systems to their limits
  • Soak tests: Evaluating performance over extended periods
  • Spike tests: Determining the maximum load the system supports
  • Breakpoint tests: Evaluating behavior with gradual increase

Basic Structure of K6 Tests

A slide showing different load test types in Portuguese and English. Types include smoke tests, average-load tests, stress tests, soak tests, spike tests, and breakpoint tests, with brief descriptions of their purposes.

Imports and Configuration

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

export const options = {
  vus: 10,       // Virtual Users
  duration: '30s' // Test duration
}
Enter fullscreen mode Exit fullscreen mode

Default Function

The core of your K6 test is the exported default function. This is where you define test scenarios:

export default function() {
  http.get('http://test.k6.io');
  sleep(1);
}
Enter fullscreen mode Exit fullscreen mode

Test Results and Metrics

K6 provides comprehensive results to understand your system's performance:

  • Thresholds: Define acceptable performance criteria
  • Detailed Metrics: Granular insights into response times, error rates, and much more
  • Customizable Outputs: Flexible reporting options

Main Tracked Metrics

 A slide titled

Recommendation:

1 - Start with small, focused tests
2 - Gradually increase load and complexity
3 - Use thresholds to define performance expectations
4 - Integrate load tests into your CI/CD pipeline
5 - Analyze results thoroughly and improve iteratively

Practical Example

Let's demonstrate a simple API test using K6 for the notifications module in a test API that I have here:

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

// Test settings
export const options = {
  vus: 2,
  duration: '30s'
};
Enter fullscreen mode Exit fullscreen mode

First test on a POST route that requires authentication:

export function testGetNotifications() {
  const params = {
    headers: {
      'Authorization': `Bearer ${AUTH_TOKEN}`,
      'Content-Type': 'application/json'
    }
  };

  const res = http.get(`${BASE_URL}/notifications`, params);

  check(res, {
    'GET status is 200': (r) => r.status === 200,
    'has notifications': (r) => {
      const body = JSON.parse(r.body);
      return body.length > 0;
    }
  });
}
Enter fullscreen mode Exit fullscreen mode

Second test on a GET route that requires authentication:

export function testPostNotification() {
  const payload = JSON.stringify({
    description: 'K6 notification test',
    notification_category: 'system',
    user_id: 1
  });

  const params = {
    headers: {
      'Authorization': `Bearer ${AUTH_TOKEN}`,
      'Content-Type': 'application/json'
    }
  };

  const res = http.post(`${BASE_URL}/notifications`, payload, params);

  check(res, {
    'POST status is 201': (r) => r.status === 201
  });
}
Enter fullscreen mode Exit fullscreen mode

Main Function that Runs the Tests in K6:

export default function() {
  testGetNotifications();
  testPostNotification();

  sleep(1);
}
Enter fullscreen mode Exit fullscreen mode

To run it, just have K6 installed on your machine and run the command k6 run script.js.

A slide showing

Results

A terminal screen showing the execution of a k6 performance testing tool. The command runs a script against a base URL with an authentication token. The test is running with 2 virtual users for a maximum duration of 30 seconds.

  • All checks passed: 100% (168 of 168 checks)
  • Virtual Users (VUs): 2
  • Test Duration: 30 seconds

  • Transferred Data

    • Received: 24 MB (759 kB/s)
    • Sent: 41 kB (1.3 kB/s)
  • Requests

    • Total requests: 112
    • Request rate: 3.51 requests per second
  • Request Times

    • Average request time: 43.78 ms
    • Minimum time: 9.88 ms
    • Average wait time: 40.75 ms
    • Maximum time: 83.57 ms
  • Performance

    • No requests failed (0.00% http_req_failed)
    • 90% of requests completed in up to 77.72 ms
    • 95% of requests completed in up to 79.48 ms
  • Iterations

    • Total iterations: 56
    • Average iteration duration: 1.1 seconds

Interpretation

  • The test was very stable
  • The API responded quickly (< 84 ms per request)
  • All GET and POST tests passed
  • The system handled the load of 2 virtual users well
  • There were no request failures

Conclusion

K6 offers developers a powerful and flexible approach to performance testing. By integrating load tests early and frequently, you can identify and resolve performance issues before they reach production.

Resources

Complete code on my GitHub:

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

đź‘‹ Kindness is contagious

Please consider leaving a ❤️ or a friendly comment if you found this post helpful!

Okay