How best to tackle tests that download very large files?

Hey

I’m currently trying to figure out the best solution for a problem we’ve been seeing in some of our tests.

The situation specifically is we have GET tests that target endpoints with very large file downloads. This is by design, we wanted to test how the application handles requests for large files at scale and see how long it takes to process. We always measure TTFB here so we’re not actually bothered too much about the file download itself except for the fact it’ll be putting realistic strain on the server.

We also measure RPS though and in this situation it’s affected drastically but the available bandwidth between the box running k6 and the server. The lower the bandwidth the worse RPS is as it waits for the downloads to finish and this leads to inconsistent tests between setups, i.e. it’s the network that “failed” the test and not the application.

Has anyone come across anything like this before? Any best practice advice?

Cheers,
gy

Hey @gygitlab

if you only care about the time to first byte and you don’t care about the full http_req_duration, you can set a timeout on the request like this:

let ttfbMetric = Trend('ttfbMetric');

export default function() {
  let res = http.get('https://httpbin.test.k6.io/range/102400', {
    timeout: 222, // timeout is specified in ms.
  });

  let req_ttfb = res.timings['waiting'] + res.timings['connecting'] + res.timings['blocked'];
  ttfbMetric.add(req_ttfb);
}

All your requests will have res.status equal to 0 due to the timeout, but you will be able to view the ttfb metric.

Here’s how it looks in k6 cloud: app.k6.io - Performance testing for developers, like unit-testing, for performance

image

I suggest using the discardResponseBodies option globally, or setting responseType: "none" on individual requests. This way k6 will read the whole response, but it will not store it in memory.

Other than that, I guess it depends on how your service works. @pawel’s suggestion could work, but, depending on how your backend works, if it might be the case that interrupting the requests midway through won’t stress it in the same way as when you read through the whole response. If that case, I don’t think you can find a workaround.