Technical Writing

Learning K6 the Hard Way

28-02-2026

A year ago, we decided to replace Akamai CloudTest with K6.

Two reasons.

First, Akamai felt rigid. Designing and tweaking tests was painful. Second, the cost.

K6 looked flexible and developer-friendly. And we had a new advantage: AI.

We believed this was a safe component to vibe code, since it wasn’t core product code. It was just test scripts. So we used Cursor.

We followed a simple approach to vibe code it: Export a HAR file from Chrome’s network tab. Drop it into a Cursor chat. Ask Cursor to recreate it in K6.

Within a week, we had a working suite covering our core APIs. We integrated it into our CI pipeline. Numbers started flowing in. We even asked Cursor to generate runner files so we could simulate different load profiles. It wrote a wrapper script to run everything in one go.

For a year, we ran the suite with a single concurrent user. Three iterations. We tracked average response times to catch performance regressions after application code changes.

Until last month, it worked perfectly. But when we were asked to test with 100–500 concurrent users, we realized something wrong:

We hadn’t built a load testing suite. We had built a single-user API runner.

The wrapper script Cursor generated wasn’t designed for real concurrency. We went back and asked it to "make it work for concurrent users". It produced another wrapper, distributing virtual users and weights across files.

Still, the servers showed only 20–30 requests per minute.

That’s when it hit us.

We never built it right. We just built it.

So we went back to fundamentals. We studied how load testing actually works. We revisited K6’s capabilities. We read through the k6-learn documentation carefully. This time, we designed before we generated.

We still used Cursor, but with a plan in our hands. We knew what we wanted. More importantly, we knew what we did not want: no wrapper scripts.

K6 already supports multiple scenarios in a single run. We refactored everything using proper load profiles and scenario configurations. Each profile could be changed from the CLI. This time, we kept it clean and native.

And it worked.

Learnings

  • A tool is only as good as your understanding of it. No matter how good your frying pan is, you can’t make a proper omelette if you don’t know how to cook. We had a fancy and powerful frying pan in Cursor, but we didn’t know how to cook.

  • Did AI fail? Not really. It gave us exactly what we asked for. AI is built to please humans. It responds to prompts, not intent. If you ask it to "recreate this HAR in K6", it will. It won’t challenge your strategy. If you ask it to make a single-line command to run all the scripts, it will create one. It won’t tell you there is a better built-in alternative or that you shouldn’t build it this way. That responsibility is still ours.

  • We still have to be engineers. Engineers design systems before they build them. AI can help us build faster. It can pour the concrete into the structure, but it won’t be the architect. It won’t set the foundation. The foundation is still a human’s job.