Lighthouse tests one user at a time. Load testing answers a different question: how does your application perform when hundreds or thousands of users hit it simultaneously? k6 is a modern, developer-friendly load testing tool that uses JavaScript for test scripts.
What Is Load Testing?
Load testing simulates concurrent users to measure how your system handles traffic. It reveals:
- Throughput: How many requests per second can your server handle?
- Latency under load: Do response times degrade as users increase?
- Breaking points: At what load does the system start failing?
- Resource bottlenecks: Is it CPU, memory, database connections, or network bandwidth?
Installing k6
k6 is a standalone binary — no Node.js runtime needed:
# macOS
brew install k6
# Windows (with Chocolatey)
choco install k6
# Docker
docker run --rm -i grafana/k6 run - < script.js
# Or download from https://k6.io/docs/get-started/installation/
Writing Your First Load Test
Create a file called load-test.js:
Run it:
k6 run load-test.jsEach virtual user (VU) executes the default function in a loop for the specified duration. The check() function validates response conditions, and sleep() simulates realistic user pauses between actions.
Ramp-Up Patterns
Real traffic does not arrive all at once. Use stages to simulate gradual increases:
This pattern is called a "stepped load test." It helps you identify at what level of concurrency performance starts to degrade.
Other Common Patterns
- Spike test: Ramp to a very high number quickly, then drop. Tests how the system handles sudden traffic surges.
- Soak test: Run at moderate load for hours. Finds memory leaks and resource exhaustion over time.
- Stress test: Gradually increase beyond expected capacity to find the breaking point.
Thresholds
Thresholds define pass/fail criteria for your load test. If any threshold is breached, k6 exits with a non-zero code — perfect for CI:
The p(95) syntax means the 95th percentile — 95% of all requests should complete within the specified time. This is more meaningful than average response time because averages hide outliers.
Testing Multiple Endpoints
Real users do not just hit the homepage. Simulate a realistic scenario:
Reading Results
After a test run, k6 prints a summary with key metrics:
- http_req_duration: Response time statistics (avg, min, med, max, p90, p95, p99).
- http_reqs: Total number of requests and requests per second.
- http_req_failed: Percentage of failed requests.
- vus: Number of active virtual users over time.
- checks: How many checks passed versus failed.
For persistent storage and visualization, you can stream results to Grafana Cloud, InfluxDB, or a CSV file:
k6 run --out csv=results.csv load-test.jsKey Takeaways
- k6 simulates concurrent users to reveal how your system performs under load.
- Use
stagesfor realistic ramp-up patterns instead of constant load. - Set
thresholdsto enforce performance requirements and fail CI when they are breached. - Focus on p95 response times, not averages — they reveal the experience of your slowest users.
- Test multiple endpoints to simulate realistic user journeys.