API Load Testing with k6
This project tests the performance and reliability of REST API endpoints using k6 with JavaScript. The APIs tested include users, posts, and todos — covering create, read, and other common operations. The goal was simple: make sure the API can handle real-world traffic without falling apart.
Project structure
The project is split into two clear layers — test scripts and a shared config file. The config file holds all the base URLs, endpoint paths, and test data constants. The test scripts import from that config, so if an endpoint changes, there's only one place to update it.
the implementation
Centralized Config
All API base URLs, endpoint names, and test data constants live in a single config file. No hardcoded URLs scattered across test files. Changing the target environment means updating one value — everything else follows automatically.
Load Test Scenarios
Each test script defines its own load stages — how many virtual users are ramped up, held, and ramped down over time. A typical scenario looks like this:
01.
Ramp up
gradually increase virtual users to simulate growing traffic
02.
Sustained load
hold at peak traffic to stress the system
03.
Ramp down
gradually reduce users back to baseline
Thresholds — Defining What "Pass" Means
This is one of the most important parts of a load test. Without thresholds, a test just produces numbers. With thresholds, it produces a pass or fail verdict.
01.
95% of requests must complete under 1000ms
ensures the API stays responsive under load
02.
Error rate must stay below 1%
ensures the API stays stable, not just fast
03.
More than 75% of checks must pass
ensures business logic is still correct under pressure
Dynamic Test Data
Each virtual user sends unique data on every request. Field values are generated using timestamps so no two requests are identical. This prevents caching from masking real performance issues and makes the test more realistic.
API Checks
Beyond just measuring speed, each request is validated with explicit checks the response status must match the expected HTTP code (e.g. 201 for a create operation) and the response time must be within an acceptable range per request. These checks run on every single request across all virtual users, giving a clear picture of how the API behaves at scale — not just in isolation.
the testing stack
Every tool chosen with purpose — from feature to assertion.
K6
for scripting and running load tests against REST APIs
Jenkins
runs the load tests automatically as part of the CI/CD pipeline