AWS re:Invent happy hour: Dec 1, 6 PM PST at MGM Grand RSVP

Kubernetes Load Testing Comparison: Speedscale vs k6

Kubernetes Load Testing Comparison: Speedscale vs k6

(Updated: )

In this article, you’ll be introduced to two different load testing tools that are both able to work with Kubernetes; Speedscale and k6. Throughout this post you’ll be given a comparative view of how each tool performs in five different categories: Ease of setup, developer experience, working with the CLI, creating tests, and integration into CI/CD pipelines.

Companies are deploying workloads in Kubernetes and times are changing. Well, companies have been deploying workloads to Kubernetes for quite some time now, and many are running their workloads effectively, even using new technologies and venues that Kubernetes provide. But, many are still using the same tools they would use when they were running their services on regular Virtual Machines. One of the areas that many don’t think to innovate on when they move their workloads to Kubernetes is load testing. You can still use your regular tools, but have you considered what advantages you may get from load testing tools that integrate directly with Kubernetes?

First of all, you still get the same benefits that you’re getting from a regular load testing tool, making sure that your application can handle the load you expect it to handle. Second of all, you get the added benefit of being able to test directly from within your cluster, removing the need to open up your service to the outside world, or just other parts of your network. Most importantly, using a tool that can integrate into Kubernetes, you can manage more of your infrastructure in the same way, rather than hosting your applications and your tools separately.

Ease of Setup: Speedscale vs. k6

Current Kubernetes capture uses the operator and supported eBPF collector. Supported JVM traffic uses a Java instrumentation agent, which requires new pods and a JVM restart. Verify decoded inbound and outbound exchanges before saving a snapshot. For local recording without a cluster, use the explicitly configured proxymock proxy workflow.

If you prefer not to work with Helm, you can instead choose to use the speedctl CLI tool offered by Speedscale. The quick start guide will first show you how to install speedctl, either by using brew or by using an install script. Once speedctl is installed, Speedscale is installed into your Kubernetes cluster by running speedctl install, which of course is also stated in the quick start guide.

Once you’ve followed either of these options, you are ready to use Speedscale in your cluster. Thankfully, you’re not left on your own, as the quick start guide gives you a quick overview of how to observe a service using Speedscale, followed by an overview of how to replay traffic.

Getting k6 installed is also fairly straightforward. You can find installation instructions by going to the official k6 documentation, where you’ll be provided with a few different installation options. Most likely you will be using brew install k6 to install k6, however there’s also a winget or choco option for Windows. With k6 installed, you can click further through the documentation to get instructions on how to run k6 and execute tests.

LLM prompt for this step
Install k6 using the supported method for my OS and verify its version. Run my reviewed script against the explicit local test target with 10 virtual users for 30 seconds, inspect response assertions and thresholds, and save the result summary.

Speedscale provides a cluster capture-and-replay workflow and a local proxymock workflow. k6 provides scripted load generation, a Kubernetes operator, and automated execution. Choose the capture, workload, and reporting path you need; both products can participate in CI.

Developer Experience: Speedscale vs k6

When you first get started with Speedscale everything works out of the box, and you can almost immediately start running tests. Current Kubernetes capture uses the operator and supported eBPF collector. Supported JVM traffic uses a Java instrumentation agent, which requires new pods and a JVM restart. Verify decoded inbound and outbound exchanges before saving a snapshot. For local recording without a cluster, use the explicitly configured proxymock proxy workflow. More details on that to follow. Should you want to use any custom test configurations, those are easy to create as well.

Speedscale uses supported inbound and outbound exchanges to create test inputs and dependency-response mocks. Review the captured coverage and replay routing, then configure valid data and assertions for the scenario. Kubernetes integration can make that workflow part of a deployment pipeline.

Recorded fixtures, credentials, dependency coverage, and assertions need maintenance as application behavior changes. Revalidate them before relying on unattended runs.

With k6 there’s one major thing to note, which is that tests are written in Javascript. If you already know Javascript then that’s great, and you will have an easy time working with the tool. However, if you don’t know Javascript you will have to take into account that it needs to be part of your learning journey as well. The big advantage of k6 using Javascript to configure tests, is that in many cases you’ve got the whole Javascript community to help you. For example, if you need to figure out how to create a loop, that’s not k6 specific, that’s just regular Javascript.

Once you’ve gotten a hang of k6 and the way it uses Javascript, it’s fairly easy to use. The tests are executed using the k6 command line which will run the tests locally, or you can deploy a CRD to Kubernetes if you have the operator installed. Alternatively, you can use the k6 cloud offering to run the tests.

Speedscale combines captured test inputs with dependency-response simulation, while k6 supplies a programmable load driver. This heavily influences how the developer experience is perceived. In essence, both tools are easy to use. Speedscale has a bit of a steeper learning curve, but in the end provides a much more advanced use case than just running a simple load test. You also get access to service mocking, a service map, and contract testing.

k6 includes a local web dashboard and cloud reporting options. Compare the desired reporting and orchestration features alongside Speedscale’s dashboard.

Working with the CLI

Speedscale has the option of downloading the speedctl CLI tool, from which you can accomplish all the tasks you would need when using Speedscale. The help menu in speedctl is incredibly verbose with a clear overview of what commands are available, what flags are available and how they’re used. The CLI is a great alternative to the WebUI if you’re a fan of using the terminal. You’ll be able to find all the same features in the CLI as in the WebUI. speedctl allows you to use both shorthand flags like -m, or the full version of the flag --capturemode. This approach has very much become a de-facto industry standard, and is incredibly helpful. You can use the shorthand flag when typing out and executing a command in the terminal, and then use the full version in scripts to make them more understandable to others.

k6 offers CLI execution, a built-in web dashboard, and cloud options. You can create your tests, inspect a script, pause a test, etc. As covered in the section on developer experience, the k6 CLI is fairly straightforward to use. It’s clear there’s been a focus on ease of use when developing the CLI. Just like speedctl, it’s possible to use both shorthand and full flags when configuring a command, bringing with it the same benefits.

Ultimately, no CLI has a clear advantage over the other. Both tools bring with them the functionality you’d expect from any quality CLI, like a verbose help menu and accurate descriptions of flags.

Creating Tests

One of the most important aspects of a load testing tool, is how easy it is to create tests. Here is a high-level overview of how a simple test is configured in each tool.

Speedscale

Creating a test as soon as you’ve gotten Speedscale installed isn’t possible. Speedscale focuses on working with your actual data, and this walkthrough starts with recorded requests; local capture and supported schema-generated examples are separate workflows. To explain this, imagine you have a service that exposes a single API endpoint, which interacts with five third-party APIs. When you hit that API endpoint, supported capture components record the selected exchanges after capture is configured.

Save selected traffic as a snapshot, then configure and start a replay through the web UI or CLI using the current Quick Start. Choose the target, workload, transforms, dependency mocks, and assertions. An installation alone does not supply valid credentials or prove that every required exchange was captured.

Replay cleanup removes configured test resources. It does not undo side effects in live dependencies, so choose the dependency boundary and data-reset process before execution. Preserve reports and check the configured failure criteria in CI.

k6

The example below is taken from the official documentation

The first step to creating a test in k6 is to create a Javascript file. In this file, you write out your test in plain Javascript. A simple test could look like this:

import http from "k6/http";
import { sleep } from "k6";
export default function () {
  http.get("https://test.k6.io");
  sleep(1);
}

This simple test sends a request to https://test.k6.io and waits a second. You can then run the test by executing k6 run script.js with script.js being the name of the file you’ve written the test in. From here, you can configure the test to be more intensive, for example by putting more load on your service by executing k6 run script.js --vus 10 --duration 30s. A VU is a Virtual User, meaning this test will run the test with 10 concurrent users for 30 seconds. It’s also possible to specify these options directly in your test file:

import http from "k6/http";
import { sleep } from "k6";
export const options = {
  vus: 10,
  duration: "30s",
};
export default function () {
  http.get("http://test.k6.io");
  sleep(1);
}

Creating tests with k6 is fairly easy, but you do have to learn about Javascript in the process.

An interesting capability of Speedscale is that you can actually use recorded traffic to autogenerate k6 scripts for you.  If you have an established k6 testing practice, you may be able to use the record and playback capability to expedite test creation, and also use Speedscale’s mocks.

LLM prompt for this step
Adapt one k6 example to my non-production base URL. Define virtual users, finite duration, meaningful response checks, and latency/error thresholds. Verify one request first and save the bounded run summary.

How do they Compare?

Speedscale requires more setup in order to make a test, where k6 can be created without any prior setup. Which tool has the advantage depends heavily on what your use case is. k6 can test your services quickly, but you will inevitably also have to be testing the dependencies of your service, unless you’ve managed to mock the dependencies with some other tool.

Speedscale can mock calls to supported dependencies when the recorded dependency responses and replay routing are configured. Verify mock matches and unmatched traffic before treating the replay as isolated. This is extremely useful when you have third-party APIs that can be rate-limited.

So, while tests in Speedscale take a bit more effort to create, you should also take into account what advantages you are getting, and whether they are something you need. Captured inputs can reduce test authoring, but fixture updates and replay configuration still require review.

Integrating into CI/CD

Speedscale has a big focus on being able to integrate directly into CI/CD scenarios with their load testing capabilities. The ability to run tests by deploying a simple Kubernetes manifest file makes it easy to run tests from your CI/CD pipelines. The gist of using Speedscale in CI/CD goes as follows:

Start by deploying your tests by patching your service to include some specific annotations as covered previously. Once the test is done running, check the report by using speedctl, which will return a status as an ENUM, allowing you to easily make checks based on the status. Because the status is an ENUM, you can easily create a gated check, making sure your test is successful.

Because integration into any CI/CD pipeline is done via implementing a script, getting Speedscale working should be possible in any CI/CD provider, as you can see by their documentation.

k6 documents automated performance testing and CI integrations. Configure thresholds, preserve reports, and prove the job fails on an intentional defect.

Use an LLM for a scoped task

Use this prompt to work through the relevant example in your project. Choose the applicable tool or environment before making changes.

Scoped LLM prompt
Read https://speedscale.com/blog/kubernetes-load-testing-comparison-speedscale-vs-k6/ and inspect my project instructions first. Prepare a bounded k6 test for my explicit test API using reviewed virtual-user, duration, latency, and error settings. Distinguish scripted HTTP load from recorded dependency replay and choose the path that measures my stated requirement. Check installed tool help before adapting commands. Report the checks actually run, their results, and anything you could not verify.

Conclusion

Evaluate Speedscale when recorded test inputs, dependency simulation, and cluster orchestration solve the gap in your current workflow. Evaluate k6’s scripting, workload models, operator, and thresholds against the load-driving requirement.

k6 supports repeated automated tests as well as ad hoc runs. The distinction here is captured fixtures and dependency simulation versus the load-driver and scripting workflow.

Both services are great options, and which one you choose will depend on what you need. Do you want a tool that can become a big part of your infrastructure, or do you need one that can help with validation whenever you need it?

If you are interested in comparing more load testing tools for Kubernetes, check out our roundup of the 5 best load testing tools for Kubernetes

Frequently asked questions

Can I use captured traffic with k6?

Yes. Speedscale exports eligible inbound HTTP requests as a k6 script. Review the exported request data and target, then add the workload schedule, dynamic-value handling, and assertions you need. Speedscale transforms are not included in that export. Use k6 thresholds when a metric or failed check must produce a failing process exit status.

Which tool handles dependency simulation?

Speedscale’s replay workflow can supply recorded responses for supported outbound dependencies. k6 drives requests at the application; pairing it with a separate mock responder lets you isolate those downstream calls. Keep the two roles explicit. Confirm mock matches and configure unmatched traffic, because running a load driver alone does not replace the application’s dependencies.

What should a fair trial measure?

Use the same application build, request mix, data, dependency configuration, and workload model. Check delivered load, error and assertion results, latency percentiles, and generator resource use. Include setup and fixture maintenance in the comparison. An immediate mock versus a real backend, or a saturated generator versus an idle one, does not establish a general tool-speed advantage.

Sources: Export captured requests to k6, k6 checks and thresholds, Speedscale dependency mocks, Generator capacity and measurement limits, Open and closed workload models.

Capture and replay your production traffic

Speedscale records live traffic from your Kubernetes services and turns it into tests, mocks, and load tests. Run it yourself, or have our AI agents and engineers run it for you.