Load Testing.
A somewhat challenging subject for most QAs I’ve worked with. Usually, it’s ignored or done incorrectly due to a misunderstanding of what it actually means.
First, let’s clarify the difference between Load Testing and Performance Testing — they are not the same thing.
Load Testing – Literally overload your system to simulate peak and worst-case user influx scenarios. You could say that load testing is a subset of performance testing.
Performance Testing – Ensures your platform performs well under certain pre-determined loads. This is a much broader category.
I like to think of performance as an abstract idea: What is performant for X given Y? And those variables can only be defined by your organization.
We recently had an idea: what if we actually started load testing our startup app?
Thanks to K6, we discovered some cool things.
We found that we could handle about 3500 VUs over a 30-second timespan, with 50 actual users hitting a specific endpoint.
We leveraged K6 (which was super easy to set up) and used an existing Grafana dashboard to monitor P99 latency, request failures, request success rates, etc.
This small exercise gave us surprising insights:
- We’re likely over-provisioned. Since we don’t actually hit 3500 users at peak, we might be able to scale down and save some money (awww yeah 💸).
- We uncovered that we might not be using the most optimal Garbage Collection tool in Java.
The fact that all this was exposed by a simple Node app (~300 LOC) is wild. The value we got in return was way more than expected.
While I get that load testing can feel daunting, it’s 100% worth doing from time to time. We’re now better positioned for the future because we understand our limits and tip-over points.
This was a small project that I pushed for at our company, and it taught me a few key lessons:
- Never underestimate what a simple test can expose.
- Setting up Grafana and K6 with a remote write endpoint was easier than expected.
Here’s what we added to our prometheus.yml
to make it work:
remote_write:
- url: "http://localhost:9090/api/v1/write"
queue_config:
capacity: 5000
max_shards: 10
min_shards: 1
max_samples_per_send: 1000
write_relabel_configs:
- source_labels: [__name__]
regex: ".*"
action: keep
And we ran k6 scripts with:
K6_PROMETHEUS_RW_SERVER_URL=http://localhost:9090/api/v1/write \
K6_PROMETHEUS_RW_USERNAME=USERNAME \
K6_PROMETHEUS_RW_PASSWORD=PASSWORD \
k6 run -o experimental-prometheus-rw script.js